void MapPainterAgg::SetOutlineFont(const Projection& projection, const MapParameter& parameter, double size) { if (!fontEngine->load_font(parameter.GetFontName().c_str(), 0, agg::glyph_ren_outline)) { std::cout << "Cannot load font '" << parameter.GetFontName() << "'" << std::endl; return; } //fontEngine->resolution(72); fontEngine->width(size*projection.ConvertWidthToPixel(parameter.GetFontSize())); fontEngine->height(size*projection.ConvertWidthToPixel(parameter.GetFontSize())); fontEngine->hinting(true); fontEngine->flip_y(true); }
void MapPainterAgg::DrawFill(const Projection& projection, const MapParameter& parameter, const FillStyle& fillStyle, agg::path_storage& path) { if (fillStyle.GetFillColor().IsVisible()) { renderer_aa->color(agg::rgba(fillStyle.GetFillColor().GetR(), fillStyle.GetFillColor().GetG(), fillStyle.GetFillColor().GetB(), fillStyle.GetFillColor().GetA())); agg::render_scanlines(*rasterizer,*scanlineP8,*renderer_aa); } double borderWidth=projection.ConvertWidthToPixel(fillStyle.GetBorderWidth()); if (borderWidth>=parameter.GetLineMinWidthPixel()) { renderer_aa->color(agg::rgba(fillStyle.GetBorderColor().GetR(), fillStyle.GetBorderColor().GetG(), fillStyle.GetBorderColor().GetB(), fillStyle.GetBorderColor().GetA())); if (fillStyle.GetBorderDash().empty()) { agg::conv_stroke<agg::path_storage> stroke(path); stroke.width(borderWidth); stroke.line_cap(agg::round_cap); rasterizer->add_path(stroke); agg::render_scanlines(*rasterizer,*scanlineP8,*renderer_aa); } else { agg::conv_dash<agg::path_storage> dasher(path); agg::conv_stroke<agg::conv_dash<agg::path_storage> > stroke(dasher); stroke.width(borderWidth); stroke.line_cap(agg::butt_cap); for (size_t i=0; i<fillStyle.GetBorderDash().size(); i+=2) { dasher.add_dash(fillStyle.GetBorderDash()[i]*borderWidth, fillStyle.GetBorderDash()[i+1]*borderWidth); } rasterizer->add_path(stroke); agg::render_scanlines(*rasterizer,*scanlineP8,*renderer_aa); } } }
void MapPainterAgg::DrawSymbol(const Projection& projection, const MapParameter& parameter, const Symbol& symbol, double x, double y) { double minX; double minY; double maxX; double maxY; double centerX; double centerY; symbol.GetBoundingBox(minX,minY,maxX,maxY); centerX=maxX-minX; centerY=maxY-minY; for (std::list<DrawPrimitiveRef>::const_iterator p=symbol.GetPrimitives().begin(); p!=symbol.GetPrimitives().end(); ++p) { DrawPrimitive* primitive=p->Get(); if (dynamic_cast<PolygonPrimitive*>(primitive)!=NULL) { PolygonPrimitive* polygon=dynamic_cast<PolygonPrimitive*>(primitive); FillStyleRef style=polygon->GetFillStyle(); agg::path_storage path; for (std::list<Coord>::const_iterator pixel=polygon->GetCoords().begin(); pixel!=polygon->GetCoords().end(); ++pixel) { if (pixel==polygon->GetCoords().begin()) { path.move_to(x+projection.ConvertWidthToPixel(pixel->x-centerX), y+projection.ConvertWidthToPixel(maxY-pixel->y-centerY)); } else { path.line_to(x+projection.ConvertWidthToPixel(pixel->x-centerX), y+projection.ConvertWidthToPixel(maxY-pixel->y-centerY)); } } path.close_polygon(); rasterizer->add_path(path); DrawFill(projection, parameter, *style, path); } else if (dynamic_cast<RectanglePrimitive*>(primitive)!=NULL) { RectanglePrimitive* rectangle=dynamic_cast<RectanglePrimitive*>(primitive); FillStyleRef style=rectangle->GetFillStyle(); agg::path_storage path; double xPos=x+projection.ConvertWidthToPixel(rectangle->GetTopLeft().x-centerX); double yPos=y+projection.ConvertWidthToPixel(maxY-rectangle->GetTopLeft().y-centerY); double width=projection.ConvertWidthToPixel(rectangle->GetWidth()); double height=projection.ConvertWidthToPixel(rectangle->GetHeight()); path.move_to(xPos,yPos); path.line_to(xPos+width,yPos); path.line_to(xPos+width,yPos+height); path.line_to(xPos,yPos+height); path.close_polygon(); rasterizer->add_path(path); DrawFill(projection, parameter, *style, path); } else if (dynamic_cast<CirclePrimitive*>(primitive)!=NULL) { CirclePrimitive* circle=dynamic_cast<CirclePrimitive*>(primitive); FillStyleRef style=circle->GetFillStyle(); agg::path_storage path; double radius=projection.ConvertWidthToPixel(circle->GetRadius()); agg::ellipse ellipse(x+projection.ConvertWidthToPixel(circle->GetCenter().x-centerX), y+projection.ConvertWidthToPixel(maxY-circle->GetCenter().y-centerY), radius, radius); path.concat_path(ellipse); rasterizer->add_path(path); DrawFill(projection, parameter, *style, path); } } }
void MapPainterSVG::DrawLabel(const Projection& projection, const MapParameter& parameter, const LabelData& label) { if (dynamic_cast<const TextStyle*>(label.style.get())!=NULL) { const TextStyle* style=dynamic_cast<const TextStyle*>(label.style.get()); #if defined(OSMSCOUT_MAP_SVG_HAVE_LIB_PANGO) PangoFontDescription* font=GetFont(projection, parameter, label.fontSize); #endif // TODO: This is not the exact placement, we cannot just move vertical by fontSize, but we must move the actual // text height. For this we need the text bounding box in LabelData. stream << " <text"; stream << " x=\"" << label.x << "\""; stream << " y=\"" << label.y+projection.ConvertWidthToPixel(label.fontSize*parameter.GetFontSize()) << "\""; stream << " font-family=\"" << parameter.GetFontName() << "\""; stream << " font-size=\"" << projection.ConvertWidthToPixel(label.fontSize*parameter.GetFontSize()) << "\""; stream << " fill=\"" << GetColorValue(style->GetTextColor()) << "\""; if (label.alpha!=1.0) { stream << " fill-opacity=\"" << label.alpha << "\""; } stream << ">"; stream << label.text; stream << "</text>" << std::endl; /* stream << "<rect x=\"" << label.bx1 << "\"" << " y=\"" << label.by1 << "\"" <<" width=\"" << label.bx2-label.bx1 << "\"" << " height=\"" << label.by2-label.by1 << "\"" << " fill=\"none\" stroke=\"blue\"/>" << std::endl;*/ } else if (dynamic_cast<const ShieldStyle*>(label.style.get())!=NULL) { const ShieldStyle* style=dynamic_cast<const ShieldStyle*>(label.style.get()); #if defined(OSMSCOUT_MAP_SVG_HAVE_LIB_PANGO) PangoFontDescription* font=GetFont(projection, parameter, label.fontSize); #endif // Shield background stream << " <rect"; stream << " x=\"" << label.bx1 << "\""; stream << " y=\"" << label.by1 << "\""; stream << " width=\"" << label.bx2-label.bx1+1 << "\""; stream << " height=\"" << label.by2-label.by1+1 << "\""; stream << " fill=\"" << GetColorValue(style->GetBgColor()) << "\""; stream << " stroke=\"none\""; stream << "/>" << std::endl; // Shield inner border stream << " <rect"; stream << " x=\"" << label.bx1+2 << "\""; stream << " y=\"" << label.by1+2 << "\""; stream << " width=\"" << label.bx2-label.bx1+1-4 << "\""; stream << " height=\"" << label.by2-label.by1+1-4 << "\""; stream << " fill=\"none\""; stream << " stroke=\"" << GetColorValue(style->GetBorderColor()) << "\""; stream << " stroke-width=\"1\""; stream << "/>" << std::endl; // TODO: This is not the exact placement, we cannot just move vertical by fontSize, but we must move the actual // text height. For this we need the text bounding box in LabelData. stream << " <text"; stream << " x=\"" << label.x << "\""; stream << " y=\"" << label.y+projection.ConvertWidthToPixel(label.fontSize*parameter.GetFontSize()) << "\""; stream << " font-family=\"" << parameter.GetFontName() << "\""; stream << " font-size=\"" << projection.ConvertWidthToPixel(label.fontSize*parameter.GetFontSize()) << "\""; stream << " fill=\"" << GetColorValue(style->GetTextColor()) << "\""; if (label.alpha!=1.0) { stream << " fill-opacity=\"" << label.alpha << "\""; } stream << ">"; stream << label.text; stream << "</text>" << std::endl; } }
void MapPainterSVG::AfterPreprocessing(const StyleConfig& styleConfig, const Projection& projection, const MapParameter& parameter, const MapData& data) { stream << " <defs>" << std::endl; stream << " <style type=\"text/css\">" << std::endl; stream << " <![CDATA[" << std::endl; size_t nextAreaId=0; for (const auto& area: GetAreaData()) { std::map<FillStyle,std::string>::const_iterator entry=fillStyleNameMap.find(*area.fillStyle); if (entry==fillStyleNameMap.end()) { std::string name="area_"+NumberToString(nextAreaId); fillStyleNameMap.insert(std::make_pair(*area.fillStyle,name)); nextAreaId++; stream << " ." << name << " {"; stream << "fill:" << GetColorValue(area.fillStyle->GetFillColor()); if (!area.fillStyle->GetFillColor().IsSolid()) { stream << ";fill-opacity:" << area.fillStyle->GetFillColor().GetA(); } stream << ";fillRule:nonzero"; double borderWidth=projection.ConvertWidthToPixel(area.fillStyle->GetBorderWidth()); if (borderWidth>0.0) { stream << ";stroke:" << GetColorValue(area.fillStyle->GetBorderColor()); if (!area.fillStyle->GetBorderColor().IsSolid()) { stream << ";stroke-opacity:" << area.fillStyle->GetBorderColor().GetA(); } stream << ";stroke-width:" << borderWidth; if (area.fillStyle->HasBorderDashes()) { stream << ";stroke-dasharray:"; for (size_t i=0; i<area.fillStyle->GetBorderDash().size(); i++) { if (i>0) { stream << ","; } stream << area.fillStyle->GetBorderDash()[i]*borderWidth; } } } stream << "}" << std::endl; } } stream << std::endl; size_t nextWayId=0; for (const auto& way : GetWayData()) { std::map<LineStyle,std::string>::const_iterator entry=lineStyleNameMap.find(*way.lineStyle); if (entry==lineStyleNameMap.end()) { std::string name="way_"+NumberToString(nextWayId); lineStyleNameMap.insert(std::make_pair(*way.lineStyle,name)); nextWayId++; double lineWidth; if (way.lineStyle->GetWidth()==0) { lineWidth=projection.ConvertWidthToPixel(way.lineStyle->GetDisplayWidth()); } else { lineWidth=GetProjectedWidth(projection, projection.ConvertWidthToPixel(way.lineStyle->GetDisplayWidth()), way.lineStyle->GetWidth()); } stream << " ." << name << " {"; stream << "fill:none;"; stream << "stroke:" << GetColorValue(way.lineStyle->GetLineColor()); if (!way.lineStyle->GetLineColor().IsSolid()) { stream << ";stroke-opacity:" << way.lineStyle->GetLineColor().GetA(); } if (way.lineStyle->HasDashes()) { stream << ";stroke-dasharray:"; for (size_t i=0; i<way.lineStyle->GetDash().size(); i++) { if (i>0) { stream << " "; } stream << way.lineStyle->GetDash()[i]*lineWidth; } } stream << "}" << std::endl; } } stream << std::endl; stream << " ]]>" << std::endl; stream << " </style>" << std::endl; stream << " </defs>" << std::endl; stream << std::endl; }
void MapPainterOpenGL::DrawArea(const Projection& projection, const MapParameter& /*parameter*/, const MapPainter::AreaData& area) { if (area.fillStyle->GetFillColor().IsVisible()) { glColor4d(area.fillStyle->GetFillColor().GetR(), area.fillStyle->GetFillColor().GetG(), area.fillStyle->GetFillColor().GetB(), area.fillStyle->GetFillColor().GetA()); gluTessProperty(tesselator, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); gluTessBeginPolygon(tesselator, NULL); gluTessBeginContour(tesselator); for (size_t i=area.transStart; i<=area.transEnd; i++) { gluTessVertex(tesselator, (GLdouble*)&coordBuffer->buffer[i], (GLdouble*)&coordBuffer->buffer[i]); } gluTessEndContour(tesselator); if (!area.clippings.empty()) { // Clip areas within the area by using CAIRO_FILL_RULE_EVEN_ODD for (std::list<PolyData>::const_iterator c=area.clippings.begin(); c!=area.clippings.end(); c++) { const PolyData& data=*c; gluTessBeginContour(tesselator); for (size_t i=data.transStart; i<=data.transEnd; i++) { gluTessVertex(tesselator, (GLdouble*)&coordBuffer->buffer[i], (GLdouble*)&coordBuffer->buffer[i]); } gluTessEndContour(tesselator); } } gluTessEndPolygon(tesselator); } if (area.fillStyle->GetBorderWidth()>0 && area.fillStyle->GetBorderColor().IsVisible()) { double borderWidth=projection.ConvertWidthToPixel(area.fillStyle->GetBorderWidth()); glColor4d(area.fillStyle->GetBorderColor().GetR(), area.fillStyle->GetBorderColor().GetG(), area.fillStyle->GetBorderColor().GetB(), area.fillStyle->GetBorderColor().GetA()); glLineWidth(borderWidth); glBegin(GL_LINE_LOOP); for (size_t i=area.transStart; i<=area.transEnd; i++) { glVertex3d(coordBuffer->buffer[i].GetX(), coordBuffer->buffer[i].GetY(), 0.0); } glEnd(); } }