void renderLabels(cairo_t* cr, std::vector<std::pair<string, FloatPoint> >& toPlace) { cairo_save(cr); cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.5); cairo_font_face_t* font = cairo_toy_font_face_create(DEFAULT_FONT, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_face(cr, font); cairo_set_font_size(cr, 120.0); cairo_set_line_width(cr, 2.0); cairo_text_extents_t textSize; std::list<shared_ptr<Label> > labels; int i = 0; std::vector<shared_ptr<Style>> styles; for (auto& pair : toPlace) { string& text = pair.first; cairo_text_extents(cr, text.c_str(), &textSize); shared_ptr<Style> s = boost::make_shared<Style>(); s->text = text; styles.push_back(s); FloatPoint center = pair.second + FloatPoint(textSize.width/2.0, textSize.height/2.0); FloatRect owner = FloatRect(center.x, center.y, center.x, center.y); FloatPoint origin = pair.second - FloatPoint(textSize.x_bearing, textSize.y_bearing); shared_ptr<Label> l = boost::make_shared<Label>(FloatRect(pair.second, textSize.width, textSize.height), owner, s->text, s.get(), origin); cairo_rectangle(cr, l->box.minX, l->box.minY, l->box.getWidth(), l->box.getHeight()); cairo_stroke(cr); labels.push_back(l); } std::vector<shared_ptr<Label> > placed; placeLabels(labels, placed); for (auto& l: placed) { cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0); cairo_move_to(cr, l->box.minX, l->box.maxY); cairo_show_text(cr, l->style->text.str().c_str()); cairo_fill(cr); cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.5); cairo_rectangle(cr, l->box.minX, l->box.minY, l->box.getWidth(), l->box.getHeight()); cairo_fill(cr); } cairo_restore(cr); }
void renderLabels(Cairo::RefPtr<Cairo::Context> cr, std::vector<std::pair<string, FloatPoint> >& toPlace) { cr->save(); cr->set_source_rgba(0.0, 0.0, 0.0, 0.5); Cairo::RefPtr<Cairo::ToyFontFace> font = Cairo::ToyFontFace::create(DEFAULT_FONT, Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL); cr->set_font_face(font); cr->set_font_size(120.0); cr->set_line_width(2.0); Cairo::TextExtents textSize; std::list<shared_ptr<Label> > labels; int i = 0; std::vector<shared_ptr<Style>> styles; for (auto& pair : toPlace) { string& text = pair.first; cr->get_text_extents(text, textSize); shared_ptr<Style> s = boost::make_shared<Style>(); s->text = text; styles.push_back(s); FloatPoint center = pair.second + FloatPoint(textSize.width/2.0, textSize.height/2.0); FloatRect owner = FloatRect(center.x, center.y, center.x, center.y); FloatPoint origin = pair.second - FloatPoint(textSize.x_bearing, textSize.y_bearing); shared_ptr<Label> l = boost::make_shared<Label>(FloatRect(pair.second, textSize.width, textSize.height), owner, s->text, s.get(), origin); cr->rectangle(l->box.minX, l->box.minY, l->box.getWidth(), l->box.getHeight()); cr->stroke(); labels.push_back(l); } std::vector<shared_ptr<Label> > placed; placeLabels(labels, placed); for (auto& l: placed) { cr->set_source_rgba(0.0, 0.0, 0.0, 1.0); cr->move_to(l->box.minX, l->box.maxY); cr->show_text(l->style->text.str()); cr->fill(); cr->set_source_rgba(1.0, 0.0, 0.0, 0.5); cr->rectangle(l->box.minX, l->box.minY, l->box.getWidth(), l->box.getHeight()); cr->fill(); } cr->restore(); }
void Renderer::renderArea(const FixedRect& area, CairoLayer layers[], double width, double height, RenderAttributes& map, AssetCache& cache) { // sort objects into acroding to z-index std::vector<NodeId> nodes; std::vector<WayId> ways; std::vector<RelId> relations; sortObjects(map, nodes, ways, relations); // transform Mercator to tile coordinates Cairo::Matrix trans = Cairo::scaling_matrix(width / (double) area.getWidth(), height / (double) area.getHeight()); trans.translate(-area.minX, -area.minY); std::list<shared_ptr<Label> > labels; std::list<shared_ptr<Shield> > shields; // render objects and collect label positions renderObjects(layers, map, trans, nodes, ways, relations, labels, shields, cache); // sort, place and render shields std::vector<shared_ptr<Shield> > placedShields; placedShields.reserve(10); shields.sort(&CompareLabels<Shield>); placeShields(shields, placedShields); renderShields(layers[LAYER_LABELS].cr, placedShields); renderLabels<Shield>(layers[LAYER_LABELS].cr, placedShields, cache); // sort, place and render labels std::vector<shared_ptr<Label> > placedLabels; placedLabels.reserve(labels.size()); labels.sort(&CompareLabels<Label>); placeLabels(labels, placedLabels); renderLabels<Label>(layers[LAYER_LABELS].cr, placedLabels, cache); compositeLayers(layers); }
static void addXLabels(Agraph_t * gp) { Agnode_t *np; Agedge_t *ep; int cnt, i, n_objs, n_lbls; int n_nlbls = 0; /* # of unset node xlabels */ int n_elbls = 0; /* # of unset edge labels or xlabels */ int n_set_lbls = 0; /* # of set xlabels and edge labels */ int n_clbls = 0; /* # of set cluster labels */ boxf bb; pointf ur; textlabel_t* lp; label_params_t params; object_t* objs; xlabel_t* lbls; object_t* objp; xlabel_t* xlp; Agsym_t* force; int et = EDGE_TYPE(gp); if (!(GD_has_labels(gp) & NODE_XLABEL) && !(GD_has_labels(gp) & EDGE_XLABEL) && !(GD_has_labels(gp) & TAIL_LABEL) && !(GD_has_labels(gp) & HEAD_LABEL) && (!(GD_has_labels(gp) & EDGE_LABEL) || EdgeLabelsDone)) return; for (np = agfstnode(gp); np; np = agnxtnode(gp, np)) { if (ND_xlabel(np)) { if (ND_xlabel(np)->set) n_set_lbls++; else n_nlbls++; } for (ep = agfstout(gp, np); ep; ep = agnxtout(gp, ep)) { if (ED_xlabel(ep)) { if (ED_xlabel(ep)->set) n_set_lbls++; else if (HAVE_EDGE(ep)) n_elbls++; } if (ED_head_label(ep)) { if (ED_head_label(ep)->set) n_set_lbls++; else if (HAVE_EDGE(ep)) n_elbls++; } if (ED_tail_label(ep)) { if (ED_tail_label(ep)->set) n_set_lbls++; else if (HAVE_EDGE(ep)) n_elbls++; } if (ED_label(ep)) { if (ED_label(ep)->set) n_set_lbls++; else if (HAVE_EDGE(ep)) n_elbls++; } } } if (GD_has_labels(gp) & GRAPH_LABEL) n_clbls = countClusterLabels (gp); /* A label for each unpositioned external label */ n_lbls = n_nlbls + n_elbls; if (n_lbls == 0) return; /* An object for each node, each positioned external label, any cluster label, * and all unset edge labels and xlabels. */ n_objs = agnnodes(gp) + n_set_lbls + n_clbls + n_elbls; objp = objs = N_NEW(n_objs, object_t); xlp = lbls = N_NEW(n_lbls, xlabel_t); bb.LL = pointfof(INT_MAX, INT_MAX); bb.UR = pointfof(-INT_MAX, -INT_MAX); for (np = agfstnode(gp); np; np = agnxtnode(gp, np)) { bb = addNodeObj (np, objp, bb); if ((lp = ND_xlabel(np))) { if (lp->set) { objp++; bb = addLabelObj (lp, objp, bb); } else { addXLabel (lp, objp, xlp, 0, ur); xlp++; } } objp++; for (ep = agfstout(gp, np); ep; ep = agnxtout(gp, ep)) { if ((lp = ED_label(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); } else if (HAVE_EDGE(ep)) { addXLabel (lp, objp, xlp, 1, edgeMidpoint(gp, ep)); xlp++; } else { agerr(AGWARN, "no position for edge with label %s", ED_label(ep)->text); continue; } objp++; } if ((lp = ED_tail_label(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); } else if (HAVE_EDGE(ep)) { addXLabel (lp, objp, xlp, 1, edgeTailpoint(ep)); xlp++; } else { agerr(AGWARN, "no position for edge with tail label %s", ED_tail_label(ep)->text); continue; } objp++; } if ((lp = ED_head_label(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); } else if (HAVE_EDGE(ep)) { addXLabel (lp, objp, xlp, 1, edgeHeadpoint(ep)); xlp++; } else { agerr(AGWARN, "no position for edge with head label %s", ED_head_label(ep)->text); continue; } objp++; } if ((lp = ED_xlabel(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); } else if (HAVE_EDGE(ep)) { addXLabel (lp, objp, xlp, 1, edgeMidpoint(gp, ep)); xlp++; } else { agerr(AGWARN, "no position for edge with xlabel %s", ED_xlabel(ep)->text); continue; } objp++; } } } if (n_clbls) { cinfo_t info; info.bb = bb; info.objp = objp; info = addClusterObj (gp, info); bb = info.bb; } force = agfindgraphattr(gp, "forcelabels"); params.force = late_bool(gp, force, TRUE); params.bb = bb; placeLabels(objs, n_objs, lbls, n_lbls, ¶ms); if (Verbose) printData(objs, n_objs, lbls, n_lbls, ¶ms); xlp = lbls; cnt = 0; for (i = 0; i < n_lbls; i++) { if (xlp->set) { cnt++; lp = (textlabel_t *) (xlp->lbl); lp->set = 1; lp->pos = centerPt(xlp); updateBB (gp, lp); } xlp++; } if (Verbose) fprintf (stderr, "%d out of %d labels positioned.\n", cnt, n_lbls); else if (cnt != n_lbls) agerr(AGWARN, "%d out of %d exterior labels positioned.\n", cnt, n_lbls); free(objs); free(lbls); }