/** * Initialize (called by all constructors) */ void RS_Snapper::init() { snapMode = graphicView->getDefaultSnapMode(); keyEntity = nullptr; pImpData->snapSpot = RS_Vector{false}; pImpData->snapCoord = RS_Vector{false}; m_SnapDistance = 1.0; RS_SETTINGS->beginGroup("/Appearance"); snap_indicator->lines_state = RS_SETTINGS->readNumEntry("/indicator_lines_state", 1); snap_indicator->lines_type = RS_SETTINGS->readEntry("/indicator_lines_type", "Crosshair"); snap_indicator->shape_state = RS_SETTINGS->readNumEntry("/indicator_shape_state", 1); snap_indicator->shape_type = RS_SETTINGS->readEntry("/indicator_shape_type", "Circle"); RS_SETTINGS->endGroup(); RS_SETTINGS->beginGroup("Colors"); QString snap_color = RS_SETTINGS->readEntry("/snap_indicator", Colors::snap_indicator); RS_SETTINGS->endGroup(); snap_indicator->lines_pen = RS_Pen(RS_Color(snap_color), RS2::Width00, RS2::DashLine2); snap_indicator->shape_pen = RS_Pen(RS_Color(snap_color), RS2::Width00, RS2::SolidLine); snap_indicator->shape_pen.setScreenWidth(1); snapRange=getSnapRange(); }
/** * Testing function. */ void LC_SimpleTests::slotTestInsertMText() { RS_DEBUG->print("%s\n: begin\n", __func__); RS_Document* d = QC_ApplicationWindow::getAppWindow()->getDocument(); if (d) { RS_Graphic* graphic = (RS_Graphic*)d; if (graphic==NULL) { return; } RS_MText* text; RS_MTextData textData; textData = RS_MTextData(RS_Vector(10.0,10.0), 10.0, 100.0, RS_MTextData::VATop, RS_MTextData::HALeft, RS_MTextData::LeftToRight, RS_MTextData::Exact, 1.0, "LibreCAD", "iso", 0.0); text = new RS_MText(graphic, textData); text->setLayerToActive(); text->setPen(RS_Pen(RS_Color(255, 0, 0), RS2::Width01, RS2::SolidLine)); graphic->addEntity(text); } RS_DEBUG->print("%s\n: end\n", __func__); }
/** * Testing function. */ void LC_SimpleTests::slotTestInsertImage() { RS_DEBUG->print("%s\n: begin\n", __func__); RS_Document* d = QC_ApplicationWindow::getAppWindow()->getDocument(); if (d) { RS_Graphic* graphic = (RS_Graphic*)d; if (graphic==NULL) { return; } RS_Image* image; RS_ImageData imageData; imageData = RS_ImageData(0, RS_Vector(50.0,30.0), RS_Vector(0.5,0.5), RS_Vector(-0.5,0.5), RS_Vector(640,480), "/home/andrew/data/image.png", 50, 50, 0); image = new RS_Image(graphic, imageData); image->setLayerToActive(); image->setPen(RS_Pen(RS_Color(255, 0, 0), RS2::Width01, RS2::SolidLine)); graphic->addEntity(image); } RS_DEBUG->print("%s\n: end\n", __func__); }
void RS_ActionModifyAttributes::trigger() { RS_DEBUG->print("RS_ActionModifyAttributes::trigger()"); RS_AttributesData data; data.pen = RS_Pen(); data.layer = "0"; data.changeColor = false; data.changeLineType = false; data.changeWidth = false; data.changeLayer = false; if (graphic!=NULL) { if (RS_DIALOGFACTORY->requestAttributesDialog(data, *graphic->getLayerList())) { RS_Modification m(*container, graphicView); m.changeAttributes(data); } } finish(); graphicView->killSelectActions(); RS_DIALOGFACTORY->updateSelectionWidget(container->countSelected()); }
void QC_ActionGetPoint::mouseMoveEvent(QMouseEvent* e) { RS_DEBUG->print("QC_ActionGetPoint::mouseMoveEvent begin"); if (getStatus()==SetReferencePoint || getStatus()==SetTargetPoint) { RS_Vector mouse = snapPoint(e); switch (getStatus()) { case SetReferencePoint: targetPoint = mouse; break; case SetTargetPoint: if (referencePoint.valid) { targetPoint = mouse; deletePreview(); RS_Line *line =new RS_Line(preview, RS_LineData(referencePoint, mouse)); line->setPen(RS_Pen(RS_Color(0,0,0), RS2::Width00, RS2::DotLine )); preview->addEntity(line); RS_DEBUG->print("QC_ActionGetPoint::mouseMoveEvent: draw preview"); drawPreview(); preview->addSelectionFrom(*container); } break; default: break; } } RS_DEBUG->print("QC_ActionGetPoint::mouseMoveEvent end"); }
/** * Draws / deletes the current snapper spot. */ void RS_Snapper::xorSnapper() { if (!finished && snapSpot.valid) { RS_Painter* painter = graphicView->createDirectPainter(); painter->setPreviewMode(); if (snapCoord.valid) { // snap point painter->drawCircle(graphicView->toGui(snapCoord), 4); // crosshairs: if (showCrosshairs==true) { painter->setPen(RS_Pen(RS_Color(0,255,255), RS2::Width00, RS2::DashLine)); painter->drawLine(RS_Vector(0, graphicView->toGuiY(snapCoord.y)), RS_Vector(graphicView->getWidth(), graphicView->toGuiY(snapCoord.y))); painter->drawLine(RS_Vector(graphicView->toGuiX(snapCoord.x),0), RS_Vector(graphicView->toGuiX(snapCoord.x), graphicView->getHeight())); } } if (snapCoord.valid && snapCoord!=snapSpot) { painter->drawLine(graphicView->toGui(snapSpot)+RS_Vector(-5,0), graphicView->toGui(snapSpot)+RS_Vector(-1,4)); painter->drawLine(graphicView->toGui(snapSpot)+RS_Vector(0,5), graphicView->toGui(snapSpot)+RS_Vector(4,1)); painter->drawLine(graphicView->toGui(snapSpot)+RS_Vector(5,0), graphicView->toGui(snapSpot)+RS_Vector(1,-4)); painter->drawLine(graphicView->toGui(snapSpot)+RS_Vector(0,-5), graphicView->toGui(snapSpot)+RS_Vector(-4,-1)); } graphicView->destroyPainter(); visible = !visible; } }
/** * Adds an entity to this preview and removes any attributes / layer * connectsions before that. */ void RS_Preview::addEntity(RS_Entity* entity) { if (entity==NULL || entity->isUndone()) { return; } // only border preview for complex entities: //if ((entity->count() > maxEntities-count()) && bool addBorder = false; if (entity->rtti()==RS2::EntityImage || entity->rtti()==RS2::EntityHatch || entity->rtti()==RS2::EntityInsert) { addBorder = true; } else { if (entity->isContainer() && entity->rtti()!=RS2::EntitySpline) { if (entity->countDeep() > maxEntities-countDeep()) { addBorder = true; } } } if (addBorder) { RS_Vector min = entity->getMin(); RS_Vector max = entity->getMax(); RS_Line* l1 = new RS_Line(this, RS_LineData(RS_Vector(min.x, min.y), RS_Vector(max.x, min.y))); RS_Line* l2 = new RS_Line(this, RS_LineData(RS_Vector(max.x, min.y), RS_Vector(max.x, max.y))); RS_Line* l3 = new RS_Line(this, RS_LineData(RS_Vector(max.x, max.y), RS_Vector(min.x, max.y))); RS_Line* l4 = new RS_Line(this, RS_LineData(RS_Vector(min.x, max.y), RS_Vector(min.x, min.y))); RS_EntityContainer::addEntity(l1); RS_EntityContainer::addEntity(l2); RS_EntityContainer::addEntity(l3); RS_EntityContainer::addEntity(l4); delete entity; entity = NULL; } else { entity->setLayer(NULL); entity->setSelected(false); entity->reparent(this); entity->setPen(RS_Pen(RS_Color(255,255,255), RS2::Width00, RS2::SolidLine)); RS_EntityContainer::addEntity(entity); } }
/** * Implementation of update. Updates the arrow. */ void RS_Leader::update() { // find and delete arrow: for(auto e: entities){ if (e->rtti()==RS2::EntitySolid) { removeEntity(e); break; } } if (isUndone()) { return; } RS_Entity* fe = firstEntity(); if (fe && fe->isAtomic()) { RS_Vector p1 = ((RS_AtomicEntity*)fe)->getStartpoint(); RS_Vector p2 = ((RS_AtomicEntity*)fe)->getEndpoint(); // first entity must be the line which gets the arrow: if (hasArrowHead()) { RS_Solid* s = new RS_Solid(this, RS_SolidData()); s->shapeArrow(p1, p2.angleTo(p1), getGraphicVariableDouble("$DIMASZ", 2.5)* getGraphicVariableDouble("$DIMSCALE", 1.0)); s->setPen(RS_Pen(RS2::FlagInvalid)); s->setLayer(nullptr); RS_EntityContainer::addEntity(s); } } calculateBorders(); }
/** * Implementation of update. Updates the arrow. */ void RS_Leader::update() { // find and delete arrow: for (RS_Entity* e=firstEntity(); e!=NULL; e=nextEntity()) { if (e->rtti()==RS2::EntitySolid) { removeEntity(e); break; } } if (isUndone()) { setVisible(false); return; } RS_Entity* fe = firstEntity(); if (fe!=NULL && fe->isAtomic()) { RS_Vector p1 = ((RS_AtomicEntity*)fe)->getStartpoint(); RS_Vector p2 = ((RS_AtomicEntity*)fe)->getEndpoint(); // first entity must be the line which gets the arrow: if (hasArrowHead()) { RS_Solid* s = new RS_Solid(this, RS_SolidData()); s->shapeArrow(p1, p2.angleTo(p1), getGraphicVariableDouble("$DIMASZ", 2.5)); s->setPen(RS_Pen(RS2::FlagInvalid)); s->setLayer(NULL); RS_EntityContainer::addEntity(s); } } }
/** * Testing function. */ void LC_SimpleTests::slotTestUnicode() { RS_DEBUG->print("%s\n: begin\n", __func__); auto appWin= QC_ApplicationWindow::getAppWindow(); appWin->slotFileOpen("./fonts/unicode.cxf", RS2::FormatCXF); RS_Document* d =appWin->getDocument(); if (d) { RS_Graphic* graphic = (RS_Graphic*)d; if (graphic==NULL) { return; } RS_Insert* ins; int col; int row; QChar uCode; // e.g. 65 (or 'A') QString strCode; // unicde as string e.g. '[0041] A' graphic->setAutoUpdateBorders(false); for (col=0x0000; col<=0xFFF0; col+=0x10) { printf("col: %X\n", col); for (row=0x0; row<=0xF; row++) { //printf(" row: %X\n", row); uCode = QChar(col+row); //printf(" code: %X\n", uCode.unicode()); strCode.setNum(uCode.unicode(), 16); while (strCode.length()<4) { strCode="0"+strCode; } strCode = "[" + strCode + "] " + uCode; if (graphic->findBlock(strCode)) { RS_InsertData d(strCode, RS_Vector(col/0x10*20.0,row*20.0), RS_Vector(1.0,1.0), 0.0, 1, 1, RS_Vector(0.0, 0.0), NULL, RS2::NoUpdate); ins = new RS_Insert(graphic, d); ins->setLayerToActive(); ins->setPen(RS_Pen(RS_Color(255, 255, 255), RS2::Width01, RS2::SolidLine)); ins->update(); graphic->addEntity(ins); } } } graphic->setAutoUpdateBorders(true); graphic->calculateBorders(); } RS_DEBUG->print("%s\n: end\n", __func__); }
/** * Constructor. * * @param parent Parent of the document. Often that's NULL but * for blocks it's the blocklist. */ RS_Document::RS_Document(RS_EntityContainer* parent) : RS_EntityContainer(parent), RS_Undo() { RS_DEBUG->print("RS_Document::RS_Document() "); filename = ""; formatType = RS2::FormatUnknown; setModified(false); RS_Color col(RS2::FlagByLayer); activePen = RS_Pen(col, RS2::WidthByLayer, RS2::LineByLayer); }
void DL_Jww::CreateTen(DL_CreationInterface* creationInterface, CDataTen& DTen) { string lName = HEX[DTen.m_nGLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DTen.m_nGLayer] + "-" + HEX[DTen.m_nLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DTen.m_nLayer]; // add layer creationInterface->addLayer(DL_LayerData(lName,0)); int width; if(DTen.m_nPenWidth > 26) width = 0; else width = DTen.m_nPenWidth; int color = colTable[DTen.m_nPenColor > ArraySize(colTable)-1 ? ArraySize(colTable)-1 : DTen.m_nPenColor]; attrib = DL_Attributes(values[8], // layer color, // color width, // width lTable[DTen.m_nPenStyle > ArraySize(lTable)-1 ? ArraySize(lTable)-1 : DTen.m_nPenStyle]); // linetype creationInterface->setAttributes(attrib); creationInterface->setExtrusion(0.0, 0.0, 1.0, 0.0 ); DL_PointData d(DTen.m_start.x, DTen.m_start.y, 0.0); creationInterface->addPoint(d); #ifdef FINISHED RS_PointData data2(RS_Vector(0.0, 0.0)); RS_Point* point; data2.pos = RS_Vector(DTen.m_start.x, DTen.m_start.y); point = new RS_Point(graphic, data2); RS2::LineType ltype = lTable[DTen.m_nPenStyle]; RS_Color col = colTable[DTen.m_nPenColor]; RS2::LineWidth lw = lWidth[DTen.m_nPenWidth > 26 ? 0 :DTen.m_nPenWidth];//RS2::Width12 point->setPen(RS_Pen(col, RS2::Width23, ltype)); //画層設定 RS_String lName = HEX[DTen.m_nGLayer > 0x0f ? 0 : DTen.m_nGLayer] + "-" + HEX[DTen.m_nLayer > 0x0f ? 0: DTen.m_nLayer]; if( graphic->findLayer(lName) == (RS_Layer*)NULL ){ #ifdef DEBUG std::cout << lName.ascii() << std::endl; #endif RS_Layer* layer = new RS_Layer(lName); graphic->addLayer(layer); } point->setLayer(lName); // add the line to the graphic graphic->addEntity(point); #ifdef DEBUG std::cout << *point; #endif #endif }
void QC_ActionGetPoint::mouseMoveEvent(QMouseEvent* e) { RS_DEBUG->print("QC_ActionGetPoint::mouseMoveEvent begin"); RS_Vector mouse = snapPoint(e); if(setTargetPoint){ if (referencePoint.valid) { targetPoint = mouse; deletePreview(); RS_Line *line =new RS_Line(preview, RS_LineData(referencePoint, mouse)); line->setPen(RS_Pen(RS_Color(0,0,0), RS2::Width00, RS2::DotLine )); preview->addEntity(line); RS_DEBUG->print("QC_ActionGetPoint::mouseMoveEvent: draw preview"); drawPreview(); preview->addSelectionFrom(*container); } } else { targetPoint = mouse; } RS_DEBUG->print("QC_ActionGetPoint::mouseMoveEvent end"); }
void QG_GraphicView::layerActivated(RS_Layer *layer) { RS_SETTINGS->beginGroup("/Modify"); bool toActivated= (RS_SETTINGS->readNumEntry("/ModifyEntitiesToActiveLayer", 0)==1); RS_SETTINGS->endGroup(); if(!toActivated) return; RS_EntityContainer *container = this->getContainer(); //allow undo cycle for layer change of selected RS_AttributesData data; data.pen = RS_Pen(); data.layer = layer->getName(); data.changeColor = false; data.changeLineType = false; data.changeWidth = false; data.changeLayer = true; RS_Modification m(*container, this); m.changeAttributes(data); container->setSelected(false); redraw(RS2::RedrawDrawing); }
/** * Adds a vertex from the endpoint of the last element or * sets the startpoint to the point 'v'. * * The very first vertex added is the starting point. * * @param v vertex coordinate * * @return Pointer to the entity that was addded or NULL if this * was the first vertex added. */ RS_Entity* RS_Leader::addVertex(const RS_Vector& v) { RS_Entity* entity=NULL; static RS_Vector last = RS_Vector(false); if (empty) { last = v; empty = false; } else { // add line to the leader: entity = new RS_Line(this, RS_LineData(last, v)); entity->setPen(RS_Pen(RS2::FlagInvalid)); entity->setLayer(NULL); RS_EntityContainer::addEntity(entity); if (count()==1 && hasArrowHead()) { update(); } last = v; } return entity; }
/** * Adds a vertex from the endpoint of the last element or * sets the startpoint to the point 'v'. * * The very first vertex added is the starting point. * * @param v vertex coordinate * * @return Pointer to the entity that was added or nullptr if this * was the first vertex added. */ RS_Entity* RS_Leader::addVertex(const RS_Vector& v) { RS_Entity* entity{nullptr}; static RS_Vector last = RS_Vector{false}; if (empty) { last = v; empty = false; } else { // add line to the leader: entity = new RS_Line{this, {last, v}}; entity->setPen(RS_Pen(RS2::FlagInvalid)); entity->setLayer(nullptr); RS_EntityContainer::addEntity(entity); if (count()==1 && hasArrowHead()) { update(); } last = v; } return entity; }
void DL_Jww::CreateEnko(DL_CreationInterface* creationInterface, CDataEnko& DEnko) { string lName = HEX[DEnko.m_nGLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DEnko.m_nGLayer] + "-" + HEX[DEnko.m_nLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DEnko.m_nLayer]; // add layer creationInterface->addLayer(DL_LayerData(lName,0)); int width; if(DEnko.m_nPenWidth > 26) width = 0; else width = DEnko.m_nPenWidth; int color = colTable[DEnko.m_nPenColor > ArraySize(colTable)-1 ? ArraySize(colTable)-1 : DEnko.m_nPenColor]; attrib = DL_Attributes(values[8], // layer color, // color width, // width lTable[DEnko.m_nPenStyle > ArraySize(lTable)-1 ? ArraySize(lTable)-1 : DEnko.m_nPenStyle]); // linetype creationInterface->setAttributes(attrib); creationInterface->setExtrusion(0.0, 0.0, 1.0, 0.0 ); double angle1, angle2; //正円 if(DEnko.m_bZenEnFlg){ if(DEnko.m_dHenpeiRitsu == 1.0){ DL_CircleData d(DEnko.m_start.x, DEnko.m_start.y, 0.0, DEnko.m_dHankei); creationInterface->addCircle(d); }else{ double angle1, angle2; if(DEnko.m_radEnkoKaku > 0.0){ angle1 = DEnko.m_radKaishiKaku; angle2 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku; }else{ angle1 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku; angle2 = DEnko.m_radKaishiKaku; } angle1 = angle1 - floor(angle1 / (M_PI * 2.0)) * M_PI * 2.0; angle2 = angle2 - floor(angle2 / (M_PI * 2.0)) * M_PI * 2.0; if( angle2 <= angle1 ) angle1 = angle1 - M_PI * 2.0; //楕円 DL_EllipseData d(DEnko.m_start.x, DEnko.m_start.y, 0.0, DEnko.m_dHankei * cos(DEnko.m_radKatamukiKaku), DEnko.m_dHankei * sin(DEnko.m_radKatamukiKaku), 0.0, DEnko.m_dHenpeiRitsu, angle1, angle2); creationInterface->addEllipse(d); } }else{ if(DEnko.m_dHenpeiRitsu == 1.0){ //円弧 if(DEnko.m_radEnkoKaku > 0.0){ angle1 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku; angle2 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku + DEnko.m_radEnkoKaku; }else{ angle1 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku + DEnko.m_radEnkoKaku; angle2 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku; } angle1 = angle1 - floor(angle1 / (M_PI * 2.0)) * M_PI * 2.0; angle2 = angle2 - floor(angle2 / (M_PI * 2.0)) * M_PI * 2.0; if( angle2 <= angle1 ) angle1 = angle1 - M_PI * 2.0; DL_ArcData d(DEnko.m_start.x, DEnko.m_start.y, 0.0, DEnko.m_dHankei, Deg(angle1), Deg(angle2)); creationInterface->addArc(d); }else{ double angle1, angle2; if(DEnko.m_radEnkoKaku > 0.0){ angle1 = DEnko.m_radKaishiKaku; angle2 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku; }else{ angle1 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku; angle2 = DEnko.m_radKaishiKaku; } angle1 = angle1 - floor(angle1 / (M_PI * 2.0)) * M_PI * 2.0; angle2 = angle2 - floor(angle2 / (M_PI * 2.0)) * M_PI * 2.0; if( angle2 <= angle1 ) angle1 = angle1 - M_PI * 2.0; //楕円 DL_EllipseData d(DEnko.m_start.x, DEnko.m_start.y, 0.0, DEnko.m_dHankei * cos(DEnko.m_radKatamukiKaku), DEnko.m_dHankei * sin(DEnko.m_radKatamukiKaku), 0.0, DEnko.m_dHenpeiRitsu, angle1, angle2); creationInterface->addEllipse(d); } } #ifdef FINISHED RS_CircleData data1(RS_Vector(0.0, 0.0), 0.0); RS_Circle* circle; RS_ArcData arc_data(RS_Vector(0.0, 0.0), 0.0, 0.0, 0.0, false); RS_Arc* arc; RS_Ellipse* elps; //正円 if(DEnko.m_bZenEnFlg){ if(DEnko.m_dHenpeiRitsu == 1.0){ data1.center = RS_Vector(DEnko.m_start.x, DEnko.m_start.y); data1.radius = DEnko.m_dHankei; circle = new RS_Circle(graphic, data1); RS2::LineType ltype = lTable[DEnko.m_nPenStyle]; RS_Color col = colTable[DEnko.m_nPenColor]; RS2::LineWidth lw = lWidth[DEnko.m_nPenWidth > 26 ? 0 : DEnko.m_nPenWidth];//RS2::Width12 circle->setPen(RS_Pen(col, lw, ltype)); RS_String lName = HEX[DEnko.m_nGLayer > 0x0f ? 0:DEnko.m_nGLayer] + "-" + HEX[DEnko.m_nLayer > 0x0f ? 0: DEnko.m_nLayer]; if( graphic->findLayer(lName) == (RS_Layer*)NULL ){ #ifdef DEBUG std::cout << lName.ascii() << std::endl; #endif RS_Layer* layer = new RS_Layer(lName); graphic->addLayer(layer); } circle->setLayer(lName); // add the line to the graphic graphic->addEntity(circle); #ifdef DEBUG std::cout << *circle; #endif }else{ //楕円 double angle1, angle2; if(DEnko.m_radEnkoKaku > 0.0){ angle1 = DEnko.m_radKaishiKaku; angle2 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku; }else{ angle1 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku; angle2 = DEnko.m_radKaishiKaku; } angle1 = angle1 - floor(angle1 / (M_PI * 2.0)) * M_PI * 2.0; angle2 = angle2 - floor(angle2 / (M_PI * 2.0)) * M_PI * 2.0; if( angle2 <= angle1 ) angle1 = angle1 - M_PI * 2.0; RS_EllipseData elps_data(RS_Vector(DEnko.m_start.x, DEnko.m_start.y), RS_Vector(DEnko.m_dHankei * cos(DEnko.m_radKatamukiKaku), DEnko.m_dHankei * sin(DEnko.m_radKatamukiKaku)), DEnko.m_dHenpeiRitsu, angle1, angle2, false); elps = new RS_Ellipse(graphic, elps_data); RS2::LineType ltype = lTable[DEnko.m_nPenStyle]; RS_Color col = colTable[DEnko.m_nPenColor]; RS2::LineWidth lw = lWidth[DEnko.m_nPenWidth > 26 ? 0 : DEnko.m_nPenWidth];//RS2::Width12 elps->setPen(RS_Pen(col, lw, ltype)); RS_String lName = HEX[DEnko.m_nGLayer > 0x0f ? 0:DEnko.m_nGLayer] + "-" + HEX[DEnko.m_nLayer > 0x0f ? 0: DEnko.m_nLayer]; if( graphic->findLayer(lName) == (RS_Layer*)NULL ){ RS_Layer* layer = new RS_Layer(lName); graphic->addLayer(layer); } elps->setLayer(lName); // add the line to the graphic graphic->addEntity(elps); } }else{ //円弧 arc_data.center = RS_Vector(DEnko.m_start.x, DEnko.m_start.y); arc_data.radius = DEnko.m_dHankei; if(DEnko.m_radEnkoKaku > 0.0){ arc_data.angle1 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku; arc_data.angle2 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku + DEnko.m_radEnkoKaku; }else{ arc_data.angle1 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku + DEnko.m_radEnkoKaku; arc_data.angle2 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku; } if( arc_data.angle2 <= arc_data.angle1 ) arc_data.angle1 = arc_data.angle1 - M_PI * 2.0; arc_data.angle1 = Deg(arc_data.angle1); arc_data.angle2 = Deg(arc_data.angle2); arc_data.reversed = false; arc = new RS_Arc(graphic, arc_data); RS2::LineType ltype = lTable[DEnko.m_nPenStyle]; RS_Color col = colTable[DEnko.m_nPenColor]; RS2::LineWidth lw = lWidth[DEnko.m_nPenWidth > 26 ? 0 : DEnko.m_nPenWidth];//RS2::Width12 arc->setPen(RS_Pen(col, lw, ltype)); RS_String lName = HEX[DEnko.m_nGLayer > 0x0f ? 0:DEnko.m_nGLayer] + "-" + HEX[DEnko.m_nLayer > 0x0f ? 0: DEnko.m_nLayer]; if( graphic->findLayer(lName) == (RS_Layer*)NULL ){ #ifdef DEBUG std::cout << lName.ascii() << std::endl; #endif RS_Layer* layer = new RS_Layer(lName); graphic->addLayer(layer); } arc->setLayer(lName); // add the line to the graphic graphic->addEntity(arc); } #endif }
void DL_Jww::CreateSen(DL_CreationInterface* creationInterface, CDataSen& DSen) { string lName = HEX[DSen.m_nGLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DSen.m_nGLayer] + "-" + HEX[DSen.m_nLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DSen.m_nLayer]; // add layer creationInterface->addLayer(DL_LayerData(lName,0)); //#ifdef DEBUG if(DSen.m_nPenStyle > ArraySize(lTable)-1) std::cout << "線種番号 " << (jwWORD)DSen.m_nPenStyle << std::endl; //線種番号 if(DSen.m_nPenColor > ArraySize(colTable)-1) std::cout << "線色番号 " << (jwWORD)DSen.m_nPenColor << std::endl; //線色番号 if(DSen.m_nPenWidth > 26) std::cout << "線色幅 " << (jwWORD)DSen.m_nPenWidth << std::endl;//線色幅 //#endif int width; if(DSen.m_nPenWidth > 26) width = 0; else width = DSen.m_nPenWidth; int color = colTable[DSen.m_nPenColor > ArraySize(colTable)-1 ? ArraySize(colTable)-1 : DSen.m_nPenColor]; attrib = DL_Attributes(values[8], // layer color, // color width, // width lTable[DSen.m_nPenStyle > ArraySize(lTable)-1 ? ArraySize(lTable)-1 : DSen.m_nPenStyle]); // linetype creationInterface->setAttributes(attrib); creationInterface->setExtrusion(0.0, 0.0, 1.0, 0.0 ); // correct some impossible attributes for layers: /* attrib = creationInterface->getAttributes(); if (attrib.getColor()==256 || attrib.getColor()==0) { attrib.setColor(7); } if (attrib.getWidth()<0) { attrib.setWidth(1); } if (!strcasecmp(attrib.getLineType().c_str(), "BYLAYER") || !strcasecmp(attrib.getLineType().c_str(), "BYBLOCK")) { attrib.setLineType("CONTINUOUS"); } */ DL_LineData d(DSen.m_start.x, DSen.m_start.y, 0.0, DSen.m_end.x, DSen.m_end.y, 0.0); creationInterface->addLine(d); #ifdef FINISHED RS_LineData data(RS_Vector(0.0, 0.0), RS_Vector(0.0, 0.0)); RS_Line* line; data.startpoint = RS_Vector(DSen.m_start.x, DSen.m_start.y); data.endpoint = RS_Vector(DSen.m_end.x, DSen.m_end.y); line = new RS_Line(graphic, data); RS2::LineType ltype = lTable[DSen.m_nPenStyle]; RS_Color col = colTable[DSen.m_nPenColor]; RS2::LineWidth lw = lWidth[DSen.m_nPenWidth>26 ? 0 : DSen.m_nPenWidth]; line->setPen(RS_Pen(col, lw, ltype)); //画層設定 //画層 // m_nGLayer-m_nLayer //_0-0_ から_0-F_ // ... //_F-0_ から_F-F_ RS_String lName = HEX[DSen.m_nGLayer > 0x0f ? 0: DSen.m_nGLayer] + "-" + HEX[DSen.m_nLayer > 0x0f ? 0: DSen.m_nLayer]; if( graphic->findLayer(lName) == (RS_Layer*)NULL ){ #ifdef DEBUG cout << jwdoc->vSen[i].m_nGLayer << " " << jwdoc->vSen[i].m_nLayer << endl; std::cout << lName.ascii() << std::endl; #endif RS_Layer* layer = new RS_Layer(lName); graphic->addLayer(layer); } line->setLayer(lName); #ifdef DEBUG std::cout << "線種番号 " << (jwWORD)DSen.m_nPenStyle << std::endl; //線種番号 std::cout << "線色番号 " << (jwWORD)DSen.m_nPenColor << std::endl; //線色番号 std::cout << "線色幅 " << (jwWORD)DSen.m_nPenWidth << std::endl;//線色幅 #endif // add the line to the graphic graphic->addEntity(line); std::cout << *line; #endif }
/** * Updates the Hatch. Called when the * hatch or it's data, position, alignment, .. changes. */ void RS_Hatch::update() { RS_DEBUG->print("RS_Hatch::update"); RS_DEBUG->print("RS_Hatch::update: contour has %d loops", count()); updateError = HATCH_OK; if (updateRunning) { return; } if (updateEnabled==false) { return; } if (data.solid==true) { calculateBorders(); return; } RS_DEBUG->print("RS_Hatch::update"); updateRunning = true; // delete old hatch: if (hatch) { removeEntity(hatch); hatch = nullptr; } if (isUndone()) { updateRunning = false; return; } if (!validate()) { RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Hatch::update: invalid contour in hatch found"); updateRunning = false; updateError = HATCH_INVALID_CONTOUR; return; } // search pattern: RS_DEBUG->print("RS_Hatch::update: requesting pattern"); RS_Pattern* pat = RS_PATTERNLIST->requestPattern(data.pattern); if (!pat) { updateRunning = false; RS_DEBUG->print("RS_Hatch::update: requesting pattern: not found"); updateError = HATCH_PATTERN_NOT_FOUND; return; } RS_DEBUG->print("RS_Hatch::update: requesting pattern: OK"); RS_DEBUG->print("RS_Hatch::update: cloning pattern"); pat = (RS_Pattern*)pat->clone(); RS_DEBUG->print("RS_Hatch::update: cloning pattern: OK"); // scale pattern RS_DEBUG->print("RS_Hatch::update: scaling pattern"); pat->scale(RS_Vector(0.0,0.0), RS_Vector(data.scale, data.scale)); pat->calculateBorders(); forcedCalculateBorders(); RS_DEBUG->print("RS_Hatch::update: scaling pattern: OK"); // find out how many pattern-instances we need in x/y: int px1, py1, px2, py2; double f; RS_Hatch* copy = (RS_Hatch*)this->clone(); copy->rotate(RS_Vector(0.0,0.0), -data.angle); copy->forcedCalculateBorders(); // create a pattern over the whole contour. RS_Vector pSize = pat->getSize(); RS_Vector rot_center=pat->getMin(); // RS_Vector cPos = getMin(); RS_Vector cSize = getSize(); RS_DEBUG->print("RS_Hatch::update: pattern size: %f/%f", pSize.x, pSize.y); RS_DEBUG->print("RS_Hatch::update: contour size: %f/%f", cSize.x, cSize.y); if (cSize.x<1.0e-6 || cSize.y<1.0e-6 || pSize.x<1.0e-6 || pSize.y<1.0e-6 || cSize.x>RS_MAXDOUBLE-1 || cSize.y>RS_MAXDOUBLE-1 || pSize.x>RS_MAXDOUBLE-1 || pSize.y>RS_MAXDOUBLE-1) { delete pat; delete copy; updateRunning = false; RS_DEBUG->print("RS_Hatch::update: contour size or pattern size too small"); updateError = HATCH_TOO_SMALL; return; } // avoid huge memory consumption: else if ( cSize.x* cSize.y/(pSize.x*pSize.y)>1e4) { RS_DEBUG->print("RS_Hatch::update: contour size too large or pattern size too small"); delete pat; delete copy; updateError = HATCH_AREA_TOO_BIG; return; } f = copy->getMin().x/pSize.x; px1 = (int)floor(f); f = copy->getMin().y/pSize.y; py1 = (int)floor(f); f = copy->getMax().x/pSize.x; px2 = (int)ceil(f); f = copy->getMax().y/pSize.y; py2 = (int)ceil(f); RS_Vector dvx=RS_Vector(data.angle)*pSize.x; RS_Vector dvy=RS_Vector(data.angle+M_PI*0.5)*pSize.y; pat->rotate(rot_center, data.angle); pat->move(-rot_center); RS_EntityContainer tmp; // container for untrimmed lines // adding array of patterns to tmp: RS_DEBUG->print("RS_Hatch::update: creating pattern carpet"); for (int px=px1; px<px2; px++) { for (int py=py1; py<py2; py++) { for(auto e: *pat){ RS_Entity* te=e->clone(); te->move(dvx*px + dvy*py); tmp.addEntity(te); } } } delete pat; pat = nullptr; delete copy; copy = nullptr; RS_DEBUG->print("RS_Hatch::update: creating pattern carpet: OK"); RS_DEBUG->print("RS_Hatch::update: cutting pattern carpet"); // cut pattern to contour shape: RS_EntityContainer tmp2; // container for small cut lines RS_Line* line = nullptr; RS_Arc* arc = nullptr; RS_Circle* circle = nullptr; RS_Ellipse* ellipse = nullptr; for(auto e: tmp){ line = nullptr; arc = nullptr; circle = nullptr; ellipse = nullptr; RS_Vector startPoint; RS_Vector endPoint; RS_Vector center = RS_Vector(false); bool reversed=false; switch(e->rtti()){ case RS2::EntityLine: line=static_cast<RS_Line*>(e); startPoint = line->getStartpoint(); endPoint = line->getEndpoint(); break; case RS2::EntityArc: arc=static_cast<RS_Arc*>(e); startPoint = arc->getStartpoint(); endPoint = arc->getEndpoint(); center = arc->getCenter(); reversed = arc->isReversed(); break; case RS2::EntityCircle: circle=static_cast<RS_Circle*>(e); startPoint = circle->getCenter() + RS_Vector(circle->getRadius(), 0.0); endPoint = startPoint; center = circle->getCenter(); break; case RS2::EntityEllipse: ellipse = static_cast<RS_Ellipse*>(e); startPoint = ellipse->getStartpoint(); endPoint = ellipse->getEndpoint(); center = ellipse->getCenter(); reversed = ellipse->isReversed(); break; default: continue; } // getting all intersections of this pattern line with the contour: QList<std::shared_ptr<RS_Vector> > is; for(auto loop: entities){ if (loop->isContainer()) { for(auto p: * static_cast<RS_EntityContainer*>(loop)){ RS_VectorSolutions sol = RS_Information::getIntersection(e, p, true); for (const RS_Vector& vp: sol){ if (vp.valid) { is.append(std::shared_ptr<RS_Vector>( new RS_Vector(vp) )); RS_DEBUG->print(" pattern line intersection: %f/%f", vp.x, vp.y); } } } } } QList<std::shared_ptr<RS_Vector> > is2;//to be filled with sorted intersections is2.append(std::shared_ptr<RS_Vector>(new RS_Vector(startPoint))); // sort the intersection points into is2 (only if there are intersections): if(is.size() == 1) {//only one intersection is2.append(is.first()); } else if(is.size() > 1) { RS_Vector sp = startPoint; double sa = center.angleTo(sp); if(ellipse ) sa=ellipse->getEllipseAngle(sp); bool done; double minDist; double dist = 0.0; std::shared_ptr<RS_Vector> av; std::shared_ptr<RS_Vector> v; RS_Vector last = RS_Vector(false); do { done = true; minDist = RS_MAXDOUBLE; av.reset(); for (int i = 0; i < is.size(); ++i) { v = is.at(i); double a; switch(e->rtti()){ case RS2::EntityLine: dist = sp.distanceTo(*v); break; case RS2::EntityArc: case RS2::EntityCircle: a = center.angleTo(*v); dist = reversed? fmod(sa - a + 2.*M_PI,2.*M_PI): fmod(a - sa + 2.*M_PI,2.*M_PI); break; case RS2::EntityEllipse: a = ellipse->getEllipseAngle(*v); dist = reversed? fmod(sa - a + 2.*M_PI,2.*M_PI): fmod(a - sa + 2.*M_PI,2.*M_PI); break; default: break; } if (dist<minDist) { minDist = dist; done = false; av = v; } } // copy to sorted list, removing double points if (!done && av.get()) { if (last.valid==false || last.distanceTo(*av)>RS_TOLERANCE) { is2.append(std::shared_ptr<RS_Vector>(new RS_Vector(*av))); last = *av; } #if QT_VERSION < 0x040400 emu_qt44_removeOne(is, av); #else is.removeOne(av); #endif av.reset(); } } while(!done); } is2.append(std::shared_ptr<RS_Vector>(new RS_Vector(endPoint))); // add small cut lines / arcs to tmp2: for (int i = 1; i < is2.size(); ++i) { auto v1 = is2.at(i-1); auto v2 = is2.at(i); if (line) { tmp2.addEntity(new RS_Line{&tmp2, *v1, *v2}); } else if (arc || circle) { if(fabs(center.angleTo(*v2)-center.angleTo(*v1)) > RS_TOLERANCE_ANGLE) {//don't create an arc with a too small angle tmp2.addEntity(new RS_Arc(&tmp2, RS_ArcData(center, center.distanceTo(*v1), center.angleTo(*v1), center.angleTo(*v2), reversed))); } } } } // updating hatch / adding entities that are inside RS_DEBUG->print("RS_Hatch::update: cutting pattern carpet: OK"); //RS_EntityContainer* rubbish = new RS_EntityContainer(getGraphic()); // the hatch pattern entities: hatch = new RS_EntityContainer(this); hatch->setPen(RS_Pen(RS2::FlagInvalid)); hatch->setLayer(nullptr); hatch->setFlag(RS2::FlagTemp); //calculateBorders(); for(auto e: tmp2){ RS_Vector middlePoint; RS_Vector middlePoint2; if (e->rtti()==RS2::EntityLine) { RS_Line* line = static_cast<RS_Line*>(e); middlePoint = line->getMiddlePoint(); middlePoint2 = line->getNearestDist(line->getLength()/2.1, line->getStartpoint()); } else if (e->rtti()==RS2::EntityArc) { RS_Arc* arc = static_cast<RS_Arc*>(e); middlePoint = arc->getMiddlePoint(); middlePoint2 = arc->getNearestDist(arc->getLength()/2.1, arc->getStartpoint()); } else { middlePoint = RS_Vector{false}; middlePoint2 = RS_Vector{false}; } if (middlePoint.valid) { bool onContour=false; if (RS_Information::isPointInsideContour( middlePoint, this, &onContour) || RS_Information::isPointInsideContour(middlePoint2, this)) { RS_Entity* te = e->clone(); te->setPen(RS2::FlagInvalid); te->setLayer(nullptr); te->reparent(hatch); hatch->addEntity(te); } } } addEntity(hatch); //getGraphic()->addEntity(rubbish); forcedCalculateBorders(); // deactivate contour: activateContour(false); updateRunning = false; RS_DEBUG->print("RS_Hatch::update: OK"); }
void RS_ActionDrawHatch::trigger() { RS_DEBUG->print("RS_ActionDrawHatch::trigger()"); //if (pos.valid) { //deletePreview(); RS_Entity* e; // deselect unhatchable entities: for(auto e: *container){ if (e->isSelected() && (e->rtti()==RS2::EntityHatch || /* e->rtti()==RS2::EntityEllipse ||*/ e->rtti()==RS2::EntityPoint || e->rtti()==RS2::EntityMText || e->rtti()==RS2::EntityText || RS_Information::isDimension(e->rtti()))) { e->setSelected(false); } } for (e=container->firstEntity(RS2::ResolveAll); e; e=container->nextEntity(RS2::ResolveAll)) { if (e->isSelected() && (e->rtti()==RS2::EntityHatch || /* e->rtti()==RS2::EntityEllipse ||*/ e->rtti()==RS2::EntityPoint || e->rtti()==RS2::EntityMText || e->rtti()==RS2::EntityText || RS_Information::isDimension(e->rtti()))) { e->setSelected(false); } } // look for selected contours: bool haveContour = false; for (e=container->firstEntity(RS2::ResolveAll); e; e=container->nextEntity(RS2::ResolveAll)) { if (e->isSelected()) { haveContour = true; } } if (!haveContour) { std::cerr << "no contour selected\n"; return; } hatch = new RS_Hatch(container, data); hatch->setLayerToActive(); hatch->setPenToActive(); RS_EntityContainer* loop = new RS_EntityContainer(hatch); loop->setPen(RS_Pen(RS2::FlagInvalid)); // add selected contour: for (RS_Entity* e=container->firstEntity(RS2::ResolveAll); e; e=container->nextEntity(RS2::ResolveAll)) { if (e->isSelected()) { e->setSelected(false); // entity is part of a complex entity (spline, polyline, ..): if (e->getParent() && // RVT - Don't de-delect the parent EntityPolyline, this is messing up the getFirst and getNext iterators // (e->getParent()->rtti()==RS2::EntitySpline || // e->getParent()->rtti()==RS2::EntityPolyline)) { (e->getParent()->rtti()==RS2::EntitySpline)) { e->getParent()->setSelected(false); } RS_Entity* cp = e->clone(); cp->setPen(RS_Pen(RS2::FlagInvalid)); cp->reparent(loop); loop->addEntity(cp); } } hatch->addEntity(loop); if (hatch->validate()) { container->addEntity(hatch); if (document) { document->startUndoCycle(); document->addUndoable(hatch); document->endUndoCycle(); } hatch->update(); graphicView->redraw(RS2::RedrawDrawing); bool printArea=true; switch( hatch->getUpdateError()) { case RS_Hatch::HATCH_OK : RS_DIALOGFACTORY->commandMessage(tr("Hatch created successfully.")); break; case RS_Hatch::HATCH_INVALID_CONTOUR : RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Invalid contour found!")); printArea=false; break; case RS_Hatch::HATCH_PATTERN_NOT_FOUND : RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Pattern not found!")); break; case RS_Hatch::HATCH_TOO_SMALL : RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Contour or pattern too small!")); break; case RS_Hatch::HATCH_AREA_TOO_BIG : RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Contour too big!")); break; default : RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Undefined Error!")); printArea=false; break; } if(m_bShowArea&&printArea){ RS_DIALOGFACTORY->commandMessage(tr("Total hatch area = %1"). arg(hatch->getTotalArea(),10,'g',8)); } } else { delete hatch; hatch = nullptr; RS_DIALOGFACTORY->commandMessage(tr("Invalid hatch area. Please check that " "the entities chosen form one or more closed contours.")); } //} }
/** * Creates a dimensioning line (line with one, two or no arrows and a text). * * @param forceAutoText Automatically reposition the text label. */ void RS_Dimension::updateCreateDimensionLine(const RS_Vector& p1, const RS_Vector& p2, bool arrow1, bool arrow2, bool forceAutoText) { // general scale (DIMSCALE) double dimscale = getGeneralScale(); // text height (DIMTXT) double dimtxt = getTextHeight()*dimscale; // text distance to line (DIMGAP) double dimgap = getDimensionLineGap()*dimscale; // length of dimension line: double distance = p1.distanceTo(p2); // arrow size: double arrowSize = getArrowSize()*dimscale; // do we have to put the arrows outside of the line? bool outsideArrows = (distance<arrowSize*2.5); // arrow angles: double arrowAngle1, arrowAngle2; // Create dimension line: RS_Line* dimensionLine = new RS_Line(this, RS_LineData(p1, p2)); dimensionLine->setPen(RS_Pen(RS2::FlagInvalid)); dimensionLine->setLayer(NULL); addEntity(dimensionLine); if (outsideArrows==false) { arrowAngle1 = dimensionLine->getAngle2(); arrowAngle2 = dimensionLine->getAngle1(); } else { arrowAngle1 = dimensionLine->getAngle1(); arrowAngle2 = dimensionLine->getAngle2(); // extend dimension line outside arrows RS_Vector dir; dir.setPolar(arrowSize*2, arrowAngle2); dimensionLine->setStartpoint(p1 + dir); dimensionLine->setEndpoint(p2 - dir); } double dimtsz=getTickSize()*dimscale; if(dimtsz < 0.01) { //display arrow // Arrows: RS_SolidData sd; RS_Solid* arrow; if (arrow1) { // arrow 1 arrow = new RS_Solid(this, sd); arrow->shapeArrow(p1, arrowAngle1, arrowSize); arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setLayer(NULL); addEntity(arrow); } if (arrow2) { // arrow 2: arrow = new RS_Solid(this, sd); arrow->shapeArrow(p2, arrowAngle2, arrowSize); arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setLayer(NULL); addEntity(arrow); } }else{ //display ticks // Arrows: RS_Line* tick; RS_Vector tickVector; tickVector.setPolar(dimtsz,arrowAngle1 + M_PI*0.25); //tick is 45 degree away if (arrow1) { // tick 1 tick = new RS_Line(this, p1-tickVector, p1+tickVector); tick->setPen(RS_Pen(RS2::FlagInvalid)); tick->setLayer(NULL); addEntity(tick); } if (arrow2) { // tick 2: tick = new RS_Line(this, p2-tickVector, p2+tickVector); tick->setPen(RS_Pen(RS2::FlagInvalid)); tick->setLayer(NULL); addEntity(tick); } } // Text label: RS_MTextData textData; RS_Vector textPos; double dimAngle1 = dimensionLine->getAngle1(); double textAngle; bool corrected=false; if (getAlignText()) textAngle =0.0; else textAngle = RS_Math::makeAngleReadable(dimAngle1, true, &corrected); if (data.middleOfText.valid && !forceAutoText) { textPos = data.middleOfText; } else { textPos = dimensionLine->getMiddlePoint(); if (!getAlignText()) { RS_Vector distV; // rotate text so it's readable from the bottom or right (ISO) // quadrant 1 & 4 if (corrected) { distV.setPolar(dimgap + dimtxt/2.0, dimAngle1-M_PI/2.0); } else { distV.setPolar(dimgap + dimtxt/2.0, dimAngle1+M_PI/2.0); } // move text away from dimension line: textPos+=distV; } //// the next update should still be able to adjust this //// auto text position. leave it invalid data.middleOfText = textPos; } textData = RS_MTextData(textPos, dimtxt, 30.0, RS_MTextData::VAMiddle, RS_MTextData::HACenter, RS_MTextData::LeftToRight, RS_MTextData::Exact, 1.0, getLabel(), "standard", textAngle); RS_MText* text = new RS_MText(this, textData); // move text to the side: RS_Vector distH; if (text->getUsedTextWidth()>distance) { distH.setPolar(text->getUsedTextWidth()/2.0 +distance/2.0+dimgap, textAngle); text->move(distH); } text->setPen(RS_Pen(RS2::FlagInvalid)); text->setLayer(NULL); //horizontal text, split dimensionLine if (getAlignText()) { double w =text->getUsedTextWidth()/2+dimgap; double h = text->getUsedTextHeight()/2+dimgap; RS_Vector v1 = textPos - RS_Vector(w, h); RS_Vector v2 = textPos + RS_Vector(w, h); RS_Line l[] = { RS_Line(NULL, RS_LineData(v1, RS_Vector(v2.x, v1.y))), RS_Line(NULL, RS_LineData(RS_Vector(v2.x, v1.y), v2)), RS_Line(NULL, RS_LineData(v2, RS_Vector(v1.x, v2.y))), RS_Line(NULL, RS_LineData(RS_Vector(v1.x, v2.y), v1)) }; RS_VectorSolutions sol1, sol2; int inters= 0; do { sol1 = RS_Information::getIntersection(dimensionLine, &(l[inters++]), true); } while (!sol1.hasValid() && inters < 4); if (!sol1.hasValid()) { do { sol2 = RS_Information::getIntersection(dimensionLine, &(l[inters++]), true); } while (!sol2.hasValid() && inters < 4); } //are text intersecting dimensionLine? if (sol1.hasValid() && sol2.hasValid()) { //yes, split dimension line RS_Line* dimensionLine2 = (RS_Line*)dimensionLine->clone(); v1 = sol1.get(0); v2 = sol2.get(0); if (p1.distanceTo(v1) < p1.distanceTo(v2)) { dimensionLine->setEndpoint(v1); dimensionLine2->setStartpoint(v2); } else { dimensionLine->setEndpoint(v2); dimensionLine2->setStartpoint(v1); } addEntity(dimensionLine2); } } addEntity(text); }
/** * Creates a vertex from the endpoint of the last element or * sets the startpoint to the point 'v'. * * The very first vertex added is the starting point. * * @param v vertex coordinate * @param bulge The bulge of the arc (see DXF documentation) * @param prepend true: Prepend instead of append at end * * @return Pointer to the entity that was created or NULL if this * was the first vertex added. */ RS_Entity* RS_Polyline::createVertex(const RS_Vector& v, double bulge, bool prepend) { RS_Entity* entity=NULL; RS_DEBUG->print("RS_Polyline::createVertex: %f/%f to %f/%f bulge: %f", data.endpoint.x, data.endpoint.y, v.x, v.y, bulge); // create line for the polyline: if (fabs(bulge)<RS_TOLERANCE) { if (prepend==false) { entity = new RS_Line(this, RS_LineData(data.endpoint, v)); } else { entity = new RS_Line(this, RS_LineData(v, data.startpoint)); } entity->setSelected(isSelected()); entity->setPen(RS_Pen(RS2::FlagInvalid)); entity->setLayer(NULL); //RS_EntityContainer::addEntity(entity); //data.endpoint = v; } // create arc for the polyline: else { bool reversed = (bulge<0.0); double alpha = atan(bulge)*4.0; double radius; RS_Vector center; RS_Vector middle; double dist; double angle; if (prepend==false) { middle = (data.endpoint+v)/2.0; dist = data.endpoint.distanceTo(v)/2.0; angle = data.endpoint.angleTo(v); } else { middle = (data.startpoint+v)/2.0; dist = data.startpoint.distanceTo(v)/2.0; angle = v.angleTo(data.startpoint); } // alpha can't be 0.0 at this point radius = fabs(dist / sin(alpha/2.0)); double wu = fabs(RS_Math::pow(radius, 2.0) - RS_Math::pow(dist, 2.0)); double h = sqrt(wu); if (bulge>0.0) { angle+=M_PI_2; } else { angle-=M_PI_2; } if (fabs(alpha)>M_PI) { h*=-1.0; } center.setPolar(h, angle); center+=middle; double a1; double a2; if (prepend==false) { a1 = center.angleTo(data.endpoint); a2 = center.angleTo(v); } else { a1 = center.angleTo(v); a2 = center.angleTo(data.startpoint); } RS_ArcData d(center, radius, a1, a2, reversed); entity = new RS_Arc(this, d); entity->setSelected(isSelected()); entity->setPen(RS_Pen(RS2::FlagInvalid)); entity->setLayer(NULL); } return entity; }
/** * Updates the sub entities of this dimension. Called when the * dimension or the position, alignment, .. changes. * * @param autoText Automatically reposition the text label */ void RS_DimAngular::update(bool /*autoText*/) { RS_DEBUG->print("RS_DimAngular::update"); clear(); if (isUndone()) { return; } // distance from entities (DIMEXO) double dimexo = getExtensionLineOffset(); // extension line extension (DIMEXE) double dimexe = getExtensionLineExtension(); // text height (DIMTXT) double dimtxt = getTextHeight(); // text distance to line (DIMGAP) double dimgap = getDimensionLineGap(); // find out center: RS_Vector center = getCenter(); if (!center.valid) { return; } double ang1 = 0.0; double ang2 = 0.0; bool reversed = false; RS_Vector p1; RS_Vector p2; getAngles(ang1, ang2, reversed, p1, p2); double rad = edata.definitionPoint4.distanceTo(center); RS_Line* line; RS_Vector dir; double len; double dist; // 1st extension line: dist = center.distanceTo(p1); len = rad - dist + dimexe; dir.setPolar(1.0, ang1); line = new RS_Line(this, RS_LineData(center + dir*dist + dir*dimexo, center + dir*dist + dir*len)); line->setPen(RS_Pen(RS2::FlagInvalid)); line->setLayer(NULL); addEntity(line); // 2nd extension line: dist = center.distanceTo(p2); len = rad - dist + dimexe; dir.setPolar(1.0, ang2); line = new RS_Line(this, RS_LineData(center + dir*dist + dir*dimexo, center + dir*dist + dir*len)); line->setPen(RS_Pen(RS2::FlagInvalid)); line->setLayer(NULL); addEntity(line); // Create dimension line (arc): RS_Arc* arc = new RS_Arc(this, RS_ArcData(center, rad, ang1, ang2, reversed)); arc->setPen(RS_Pen(RS2::FlagInvalid)); arc->setLayer(NULL); addEntity(arc); // length of dimension arc: double distance = arc->getLength(); // do we have to put the arrows outside of the arc? bool outsideArrows = (distance<getArrowSize()*2); // arrow angles: double arrowAngle1, arrowAngle2; double arrowAng; if (rad>1.0e-6) { arrowAng = getArrowSize() / rad; } else { arrowAng = 0.0; } RS_Vector v1, v2; if (!arc->isReversed()) { v1.setPolar(rad, arc->getAngle1()+arrowAng); } else { v1.setPolar(rad, arc->getAngle1()-arrowAng); } v1+=arc->getCenter(); arrowAngle1 = arc->getStartpoint().angleTo(v1); if (!arc->isReversed()) { v2.setPolar(rad, arc->getAngle2()-arrowAng); } else { v2.setPolar(rad, arc->getAngle2()+arrowAng); } v2+=arc->getCenter(); arrowAngle2 = arc->getEndpoint().angleTo(v2); if (!outsideArrows) { arrowAngle1 = arrowAngle1+M_PI; arrowAngle2 = arrowAngle2+M_PI; } // Arrows: RS_SolidData sd; RS_Solid* arrow; // arrow 1 arrow = new RS_Solid(this, sd); arrow->shapeArrow(arc->getStartpoint(), arrowAngle1, getArrowSize()); arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setLayer(NULL); addEntity(arrow); // arrow 2: arrow = new RS_Solid(this, sd); arrow->shapeArrow(arc->getEndpoint(), arrowAngle2, getArrowSize()); arrow->setPen(RS_Pen(RS2::FlagInvalid)); arrow->setLayer(NULL); addEntity(arrow); // text label: RS_TextData textData; RS_Vector textPos = arc->getMiddlePoint(); RS_Vector distV; double textAngle; double dimAngle1 = textPos.angleTo(arc->getCenter())-M_PI/2.0; // rotate text so it's readable from the bottom or right (ISO) // quadrant 1 & 4 if (dimAngle1>M_PI/2.0*3.0+0.001 || dimAngle1<M_PI/2.0+0.001) { distV.setPolar(dimgap, dimAngle1+M_PI/2.0); textAngle = dimAngle1; } // quadrant 2 & 3 else { distV.setPolar(dimgap, dimAngle1-M_PI/2.0); textAngle = dimAngle1+M_PI; } // move text away from dimension line: textPos+=distV; textData = RS_TextData(textPos, dimtxt, 30.0, RS2::VAlignBottom, RS2::HAlignCenter, RS2::LeftToRight, RS2::Exact, 1.0, getLabel(), "standard", textAngle); RS_Text* text = new RS_Text(this, textData); // move text to the side: text->setPen(RS_Pen(RS2::FlagInvalid)); text->setLayer(NULL); addEntity(text); calculateBorders(); }
/** * @param parent The graphic this block belongs to. * @param name The name of the block used as an identifier. * @param basePoint Base point (offset) of the block. */ RS_Block::RS_Block(RS_EntityContainer* parent, const RS_BlockData& d) : RS_Document(parent), data(d) { pen = RS_Pen(RS_Color(128,128,128), RS2::Width01, RS2::SolidLine); }
/** * 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; }
/** * Updates the Inserts (letters) of this text. Called when the * text or it's data, position, alignment, .. changes. * This method also updates the usedTextWidth / usedTextHeight property. */ void RS_Text::update() { RS_DEBUG->print("RS_Text::update"); clear(); if (isUndone()) { return; } usedTextWidth = 0.0; usedTextHeight = 0.0; RS_Font* font = RS_FONTLIST->requestFont(data.style); if (font==NULL) { return; } RS_Vector letterPos = RS_Vector(0.0, -9.0); RS_Vector letterSpace = RS_Vector(font->getLetterSpacing(), 0.0); RS_Vector space = RS_Vector(font->getWordSpacing(), 0.0); // First every text line is created with // alignement: top left // angle: 0 // height: 9.0 // Rotation, scaling and centering is done later // For every letter: for (int i=0; i<(int)data.text.length(); ++i) { // Space: if (data.text.at(i).unicode() == 0x20) { letterPos+=space; } else { // One Letter: QString letterText = QString(data.text.at(i)); if (font->findLetter(letterText) == NULL) { RS_DEBUG->print("RS_Text::update: missing font for letter( %s ), replaced it with QChar(0xfffd)",qPrintable(letterText)); letterText = QChar(0xfffd); } RS_DEBUG->print("RS_Text::update: insert a " "letter at pos: %f/%f", letterPos.x, letterPos.y); RS_InsertData d(letterText, letterPos, RS_Vector(1.0, 1.0), 0.0, 1,1, RS_Vector(0.0,0.0), font->getLetterList(), RS2::NoUpdate); RS_Insert* letter = new RS_Insert(this, d); RS_Vector letterWidth; letter->setPen(RS_Pen(RS2::FlagInvalid)); letter->setLayer(NULL); letter->update(); letter->forcedCalculateBorders(); letterWidth = RS_Vector(letter->getMax().x-letterPos.x, 0.0); if (letterWidth.x < 0) letterWidth.x = -letterSpace.x; // oneLine->addEntity(letter); addEntity(letter); // next letter position: letterPos += letterWidth; letterPos += letterSpace; } } if( ! RS_EntityContainer::autoUpdateBorders) { //only update borders when needed forcedCalculateBorders(); } RS_Vector textSize = getSize(); RS_DEBUG->print("RS_Text::updateAddLine: width 2: %f", textSize.x); // Vertical Align: double vSize = 9.0; //HAAligned, HAFit, HAMiddle require VABaseline if (data.halign == RS_TextData::HAAligned || data.halign == RS_TextData::HAFit || data.halign == RS_TextData::HAMiddle) { data.valign = RS_TextData::VABaseline; } RS_Vector offset(0.0, 0.0); switch (data.valign) { case RS_TextData::VAMiddle: offset.move(RS_Vector(0.0, vSize/2.0)); break; case RS_TextData::VABottom: offset.move(RS_Vector(0.0, vSize+3)); break; case RS_TextData::VABaseline: offset.move(RS_Vector(0.0, vSize)); break; default: break; } // Horizontal Align: switch (data.halign) { case RS_TextData::HAMiddle:{ offset.move(RS_Vector(-textSize.x/2.0, -(vSize + textSize.y/2.0 + getMin().y) )); break;} case RS_TextData::HACenter: RS_DEBUG->print("RS_Text::updateAddLine: move by: %f", -textSize.x/2.0); offset.move(RS_Vector(-textSize.x/2.0, 0.0)); break; case RS_TextData::HARight: offset.move(RS_Vector(-textSize.x, 0.0)); break; default: break; } if (data.halign!=RS_TextData::HAAligned && data.halign!=RS_TextData::HAFit){ data.secondPoint = RS_Vector(offset.x, offset.y - vSize); } RS_EntityContainer::move(offset); // Scale: if (data.halign==RS_TextData::HAAligned){ double dist = data.insertionPoint.distanceTo(data.secondPoint)/textSize.x; data.height = vSize*dist; RS_EntityContainer::scale(RS_Vector(0.0,0.0), RS_Vector(dist, dist)); } else if (data.halign==RS_TextData::HAFit){ double dist = data.insertionPoint.distanceTo(data.secondPoint)/textSize.x; RS_EntityContainer::scale(RS_Vector(0.0,0.0), RS_Vector(dist, data.height/9.0)); } else { RS_EntityContainer::scale(RS_Vector(0.0,0.0), RS_Vector(data.height*data.widthRel/9.0, data.height/9.0)); data.secondPoint.scale(RS_Vector(0.0,0.0), RS_Vector(data.height*data.widthRel/9.0, data.height/9.0)); } forcedCalculateBorders(); // Update actual text size (before rotating, after scaling!): usedTextWidth = getSize().x; usedTextHeight = data.height; // Rotate: if (data.halign==RS_TextData::HAAligned || data.halign==RS_TextData::HAFit){ double angle = data.insertionPoint.angleTo(data.secondPoint); data.angle = angle; } else { data.secondPoint.rotate(RS_Vector(0.0,0.0), data.angle); data.secondPoint.move(data.insertionPoint); } RS_EntityContainer::rotate(RS_Vector(0.0,0.0), data.angle); // Move to insertion point: RS_EntityContainer::move(data.insertionPoint); forcedCalculateBorders(); RS_DEBUG->print("RS_Text::update: OK"); }
void DL_Jww::CreateMoji(DL_CreationInterface* creationInterface, CDataMoji& DMoji) { string lName = HEX[DMoji.m_nGLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DMoji.m_nGLayer] + "-" + HEX[DMoji.m_nLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DMoji.m_nLayer]; // add layer creationInterface->addLayer(DL_LayerData(lName,0)); int width; if(DMoji.m_nPenWidth > 26) width = 0; else width = DMoji.m_nPenWidth; int color = colTable[DMoji.m_nPenColor > ArraySize(colTable)-1 ? ArraySize(colTable)-1 : DMoji.m_nPenColor]; attrib = DL_Attributes(values[8], // layer color, // color width, // width lTable[DMoji.m_nPenStyle > ArraySize(lTable)-1 ? ArraySize(lTable)-1 : DMoji.m_nPenStyle]); // linetype creationInterface->setAttributes(attrib); creationInterface->setExtrusion(0.0, 0.0, 1.0, 0.0 ); DL_TextData d( // insertion point DMoji.m_start.x, DMoji.m_start.y, 0.0, // alignment point 0.0, 0.0, 0.0, // height DMoji.m_dSizeY, // x scale 1.0, // generation flags 0, // h just 0, // v just 0, // text DMoji.m_string, // style string("japanese"), // angle DMoji.m_degKakudo / 180.0 * M_PI); creationInterface->addText(d); #ifdef FINISHED QTextCodec* codec = QTextCodec::codecForName("SJIS"); RS_TextData data3(RS_Vector(0.0, 0.0), 10,//double height, 10,//double width, RS2::VAlignMiddle, RS2::HAlignCenter, RS2::LeftToRight, RS2::AtLeast, 1.0,//double lineSpacingFactor, RS_String(""),//const RS_String& text, RS_String(""), 0.0,//double angle, RS2::Update); RS_Text* text; data3.insertionPoint = RS_Vector(DMoji.m_start.x, DMoji.m_start.y); data3.height = DMoji.m_dSizeY; data3.width = DMoji.m_dSizeX; data3.valign = RS2::VAlignBottom;//VAlignMiddle; data3.halign = RS2::HAlignLeft;//HAlignCenter; data3.drawingDirection = RS2::LeftToRight; data3.lineSpacingStyle = RS2::Exact; data3.lineSpacingFactor = DMoji.m_dKankaku;//1.0; //コード変換 size_t left = DMoji.m_string.length(); char* sjis = (char *)DMoji.m_string.c_str(); char buf[200]; //memset(buf, NULL, 1000); char* p = buf; size_t bufleft = 200; #ifdef _WINDOWS // エンコーディングの変換:iconvを使う場合 iconv_t cd = iconv_open(UTF8_CES, SHIFTJIS_CES); #ifdef DEBUG printf("sjis = %x, p = %x\n", sjis, p); #endif size_t r = iconv(cd, (const char **)(&sjis), &left, &p, &bufleft);//const_cast<char**> #ifdef DEBUG printf("sjis = %x, p = %x\n", sjis, p); printf("sjis = %x %x %x %x, p = %x %x %x %x\n", sjis[0],sjis[1],sjis[2],sjis[3], buf[0],buf[1],buf[2],buf[3]); printf("r = %d, left = %d, bufleft = %d\n", r, left, bufleft); #endif *p = '\0'; iconv_close(cd); #else // int ires = SJIS2UTF8N(sjis,buf,bufleft); int nBytesOut; strcpy(buf,(const char *)CUnicodeF::sjis_to_euc((const unsigned char *)sjis/*, &nBytesOut*/)); // QTextCodec* codec = QTextCodec::codecForName("eucJP"); // data3.text = codec->toUnicode(buf); #endif // data3.text = codec->toUnicode(sjis); data3.text = RS_String::fromUtf8(buf); data3.style = RS_String("japanese-euc"); data3.angle = DMoji.m_degKakudo / 180.0 * M_PI; #ifdef DEBUG RS_DEBUG->setLevel(RS_Debug::D_DEBUGGING); #endif data3.updateMode = RS2::Update; //jwDWORD m_nMojiShu;//文字種(斜体文字は20000、ボールド体は10000を加えた数値) text = new RS_Text(graphic, data3); RS2::LineType ltype = lTable[DMoji.m_nPenStyle]; RS_Color col = colTable[DMoji.m_nPenColor]; RS2::LineWidth lw = lWidth[DMoji.m_nPenWidth > 26 ? 0 : DMoji.m_nPenWidth];//RS2::Width12 text->setPen(RS_Pen(col, RS2::Width08, ltype)); //画層設定 RS_String lName = HEX[DMoji.m_nGLayer > 0x0f ? 0: DMoji.m_nGLayer] + "-" + HEX[DMoji.m_nLayer > 0x0f ? 0 : DMoji.m_nLayer]; if( graphic->findLayer(lName) == (RS_Layer*)NULL ){ #ifdef DEBUG std::cout << lName.ascii() << std::endl; #endif RS_Layer* layer = new RS_Layer(lName); graphic->addLayer(layer); } text->setLayer(lName); // add the line to the graphic graphic->addEntity(text); #ifdef DEBUG std::cout << data3.height << " " << data3.width << std::endl; std::cout << *text; #endif #endif }
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(); }
void RS_GraphicView::setPenForEntity(RS_Painter *painter,RS_Entity *e) { if (draftMode) { painter->setPen(RS_Pen(foreground, RS2::Width00, RS2::SolidLine)); } // Getting pen from entity (or layer) RS_Pen pen = e->getPen(true); int w = pen.getWidth(); if (w<0) { w = 0; } #if 1 /*TRUE*/ // - Scale pen width. // - Notes: pen width is not scaled on print and print preview. // This is the standard (AutoCAD like) behaviour. // bug# 3437941 // ------------------------------------------------------------ if (!draftMode) { double uf = 1.0; // Unit factor. double wf = 1.0; // Width factor. RS_Graphic* graphic = container->getGraphic(); if (graphic) { uf = RS_Units::convert(1.0, RS2::Millimeter, graphic->getUnit()); if ( (isPrinting() || isPrintPreview()) && graphic->getPaperScale() > RS_TOLERANCE ) { wf = 1.0 / graphic->getPaperScale(); } } pen.setScreenWidth(toGuiDX(w / 100.0 * uf * wf)); } else { // pen.setWidth(RS2::Width00); pen.setScreenWidth(0); } #else // - Scale pen width. // - Notes: pen width is scaled on print and print preview. // This is not the standard (AutoCAD like) behaviour. // -------------------------------------------------------- if (!draftMode) { double uf = 1.0; // Unit factor. RS_Graphic* graphic = container->getGraphic(); if (graphic) uf = RS_Units::convert(1.0, RS2::Millimeter, graphic->getUnit()); pen.setScreenWidth(toGuiDX(w / 100.0 * uf)); } else pen.setScreenWidth(0); #endif // prevent drawing with 1-width which is slow: if (RS_Math::round(pen.getScreenWidth())==1) { pen.setScreenWidth(0.0); } // prevent background color on background drawing: if (pen.getColor().stripFlags()==background.stripFlags()) { pen.setColor(foreground); } // this entity is selected: if (e->isSelected()) { pen.setLineType(RS2::DotLine); pen.setColor(selectedColor); } // this entity is highlighted: if (e->isHighlighted()) { pen.setColor(highlightedColor); } // deleting not drawing: if (getDeleteMode()) { pen.setColor(background); } painter->setPen(pen); }
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; } }