// Set libplot's filling-and-edging style. May set the line width to zero // to turn off edging. In libplot, a 0-width line is as narrow a line as // can be drawn. void drvplot::set_filling_and_edging_style() { switch (currentShowType()) { case drvbase::stroke: (void)plotter->flinewidth(currentLineWidth()); (void)plotter->pencolor(plotcolor(currentR()), plotcolor(currentG()), plotcolor(currentB())); (void)plotter->filltype(0); // no filling break; case drvbase::fill: if (pathWasMerged()) { (void)plotter->flinewidth(currentLineWidth()); (void)plotter->pencolor(plotcolor(edgeR()), plotcolor(edgeG()), plotcolor(edgeB())); (void)plotter->fillcolor(plotcolor(fillR()), plotcolor(fillG()), plotcolor(fillB())); } else { (void)plotter->flinewidth(0.0); // little or no edging (void)plotter->pencolor(plotcolor(currentR()), plotcolor(currentG()), plotcolor(currentB())); (void)plotter->fillcolor(plotcolor(currentR()), plotcolor(currentG()), plotcolor(currentB())); } (void)plotter->filltype(1); (void)plotter->fillmod("winding"); break; case drvbase::eofill: if (pathWasMerged()) { (void)plotter->flinewidth(currentLineWidth()); (void)plotter->pencolor(plotcolor(edgeR()), plotcolor(edgeG()), plotcolor(edgeB())); (void)plotter->fillcolor(plotcolor(fillR()), plotcolor(fillG()), plotcolor(fillB())); } else { (void)plotter->flinewidth(0.0); // little or no edging (void)plotter->pencolor(plotcolor(currentR()), plotcolor(currentG()), plotcolor(currentB())); (void)plotter->fillcolor(plotcolor(currentR()), plotcolor(currentG()), plotcolor(currentB())); } (void)plotter->filltype(1); (void)plotter->fillmod("even-odd"); break; default: // cannot happen errf << "unexpected ShowType " << (int) currentShowType(); break; } }
void drvSAMPL::show_path() { outf << "Path # " << currentNr(); if (isPolygon()) outf << " (polygon): " << endl; else outf << " (polyline): " << endl; outf << "\tcurrentShowType: "; switch (currentShowType()) { case drvbase::stroke: outf << "stroked"; break; case drvbase::fill: outf << "filled"; break; case drvbase::eofill: outf << "eofilled"; break; default: // cannot happen outf << "unexpected ShowType " << (int) currentShowType(); break; } outf << endl; outf << "\tcurrentLineWidth: " << currentLineWidth() << endl; outf << "\tcurrentR: " << currentR() << endl; outf << "\tcurrentG: " << currentG() << endl; outf << "\tcurrentB: " << currentB() << endl; outf << "\tedgeR: " << edgeR() << endl; outf << "\tedgeG: " << edgeG() << endl; outf << "\tedgeB: " << edgeB() << endl; outf << "\tfillR: " << fillR() << endl; outf << "\tfillG: " << fillG() << endl; outf << "\tfillB: " << fillB() << endl; outf << "\tcurrentLineCap: " << currentLineCap() << endl; outf << "\tdashPattern: " << dashPattern() << endl; outf << "\tPath Elements 0 to " << numberOfElementsInPath() - 1 << endl; print_coords(); }
void drvCAIRO::show_path() { DashPattern dp(dashPattern()); outf << endl; outf << " /*" << endl; outf << " * Path # " << currentNr() ; if (isPolygon()) outf << " (polygon):" << endl; else outf << " (polyline):" << endl; outf << " */" << endl; outf << endl; outf << " cairo_save (cr);" << endl; outf << " cairo_set_line_width (cr, " << currentLineWidth() << ");" << endl; // CAIRO_LINE_CAP_BUTT - start(stop) the line exactly at the start(end) point // CAIRO_LINE_CAP_ROUND - use a round ending, the center of the circle is the end point // CAIRO_LINE_CAP_SQUARE - use squared ending, the center of the square is the end point outf << " cairo_set_line_cap (cr, "; switch( currentLineCap() ) { case 0: outf << "CAIRO_LINE_CAP_BUTT);" << endl; break; case 1: outf << "CAIRO_LINE_CAP_ROUND);" << endl; break; case 2: outf << "CAIRO_LINE_CAP_SQUARE);" << endl; break; default: errf << "Unexpected currentLineCap() in cairo driver: " << currentLineCap() << endl; outf << "CAIRO_LINE_CAP_ROUND);" << endl; break; } // cairo_set_dash (cairo_t *cr, const double *dashes, int num_dashes, double offset); // dashes : // an array specifying alternate lengths of on and off stroke portions // // num_dashes : // the length of the dashes array // // offset : // an offset into the dash pattern at which the stroke should start // // dashPattern: has nrOfEntries, float *numbers, float offset if (dp.nrOfEntries > 0) { outf << " {" << endl; outf << " double pat[" << dp.nrOfEntries << "] = {" << endl; for (int i = 0; i < dp.nrOfEntries; i++) { outf << " " << dp.numbers[i] << ", " << endl; } outf << " };" << endl; outf << endl; outf << " cairo_set_dash (cr, pat, " << dp.nrOfEntries << ", " << dp.offset << ");" << endl; outf << " }" << endl; } else { outf << " cairo_set_dash (cr, NULL, 0, 0.0);" << endl; } // cairo_move_to (cr, 0.25, 0.25); // cairo_line_to (cr, 0.5, 0.375); outf << " /* Path Elements 0 to " << numberOfElementsInPath() - 1 << " */" << endl; print_coords(); switch (currentShowType()) { case drvbase::stroke: outf << " cairo_set_source_rgb (cr, " << edgeR() << "," << edgeG() << "," << edgeB() << ");" << endl; outf << " cairo_stroke (cr);" << endl; break; case drvbase::eofill: outf << " cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);" << endl; evenoddmode = true; case drvbase::fill: outf << " cairo_set_source_rgb (cr, " << fillR() << "," << fillG() << "," << fillB() << ");" << endl; outf << " cairo_fill_preserve (cr);" << endl; if (evenoddmode) { outf << " cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);" << endl; evenoddmode = false; } outf << " cairo_set_source_rgb (cr, " << edgeR() << "," << edgeG() << "," << edgeB() << ");" << endl; outf << " cairo_stroke (cr);" << endl; break; default: // cannot happen outf << " // unexpected ShowType " << (int) currentShowType(); break; } outf << " cairo_restore (cr);" << endl; }
/*! \internal */ void QGeoMapPolygonGeometry::updateScreenPoints(const QGeoMap &map) { if (!screenDirty_) return; if (map.width() == 0 || map.height() == 0) { clear(); return; } QPointF origin = map.coordinateToScreenPosition(srcOrigin_, false); // Create the viewport rect in the same coordinate system // as the actual points QRectF viewport(0, 0, map.width(), map.height()); viewport.translate(-1 * origin); QPainterPath vpPath; vpPath.addRect(viewport); QPainterPath ppi; if (clipToViewport_) ppi = srcPath_.intersected(vpPath); // get the clipped version of the path else ppi = srcPath_; clear(); // a polygon requires at least 3 points; if (ppi.elementCount() < 3) return; // Intersection between the viewport and a concave polygon can create multiple polygons // joined by a line at the viewport border, and poly2tri does not triangulate this very well // so use the full src path if the resulting polygon is concave. if (clipToViewport_) { int changeInX = 0; int changeInY = 0; QPainterPath::Element e1 = ppi.elementAt(1); QPainterPath::Element e = ppi.elementAt(0); QVector2D edgeA(e1.x - e.x ,e1.y - e.y); for (int i = 2; i <= ppi.elementCount(); ++i) { e = ppi.elementAt(i % ppi.elementCount()); if (e.x == e1.x && e.y == e1.y) continue; QVector2D edgeB(e.x - e1.x, e.y - e1.y); if ((edgeA.x() < 0) == (edgeB.x() >= 0)) changeInX++; if ((edgeA.y() < 0) == (edgeB.y() >= 0)) changeInY++; edgeA = edgeB; e1 = e; } if (changeInX > 2 || changeInY > 2) // polygon is concave ppi = srcPath_; } // translate the path into top-left-centric coordinates QRectF bb = ppi.boundingRect(); ppi.translate(-bb.left(), -bb.top()); firstPointOffset_ = -1 * bb.topLeft(); ppi.closeSubpath(); screenOutline_ = ppi; std::vector<p2t::Point*> curPts; curPts.reserve(ppi.elementCount()); for (int i = 0; i < ppi.elementCount(); ++i) { const QPainterPath::Element e = ppi.elementAt(i); if (e.isMoveTo() || i == ppi.elementCount() - 1 || (qAbs(e.x - curPts.front()->x) < 0.1 && qAbs(e.y - curPts.front()->y) < 0.1)) { if (curPts.size() > 2) { p2t::CDT *cdt = new p2t::CDT(curPts); cdt->Triangulate(); std::vector<p2t::Triangle*> tris = cdt->GetTriangles(); screenVertices_.reserve(screenVertices_.size() + int(tris.size())); for (size_t i = 0; i < tris.size(); ++i) { p2t::Triangle *t = tris.at(i); for (int j = 0; j < 3; ++j) { p2t::Point *p = t->GetPoint(j); screenVertices_ << Point(p->x, p->y); } } delete cdt; } curPts.clear(); curPts.reserve(ppi.elementCount() - i); curPts.push_back(new p2t::Point(e.x, e.y)); } else if (e.isLineTo()) { curPts.push_back(new p2t::Point(e.x, e.y)); } else { qWarning("Unhandled element type in polygon painterpath"); } } if (curPts.size() > 0) { qDeleteAll(curPts.begin(), curPts.end()); curPts.clear(); } screenBounds_ = ppi.boundingRect(); }