box2d<double> placement_finder::get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot) { /* (0/ymax) (width/ymax) *************** * * (0/0)* * * * *************** (0/ymin) (width/ymin) Add glyph offset in y direction, but not in x direction (as we use the full cluster width anyways)! */ double width = layout.cluster_width(glyph.char_index); if (glyph.advance() <= 0) width = -width; pixel_position tmp, tmp2; tmp.set(0, glyph.ymax()); tmp = tmp.rotate(rot); tmp2.set(width, glyph.ymax()); tmp2 = tmp2.rotate(rot); box2d<double> bbox(tmp.x, -tmp.y, tmp2.x, -tmp2.y); tmp.set(width, glyph.ymin()); tmp = tmp.rotate(rot); bbox.expand_to_include(tmp.x, -tmp.y); tmp.set(0, glyph.ymin()); tmp = tmp.rotate(rot); bbox.expand_to_include(tmp.x, -tmp.y); pixel_position pos2 = pos + pixel_position(0, glyph.offset.y).rotate(rot); bbox.move(pos2.x , -pos2.y); return bbox; }
void text_symbolizer_properties::process(text_layout & output, feature_impl const& feature, attributes const& attrs) //const { output.clear(); if (tree_) { evaluate_text_properties(feature, attrs); //evaluate format properties evaluated_format_properties_ptr format = std::make_shared<detail::evaluated_format_properties>(); format->text_size = util::apply_visitor(extract_value<value_double>(feature,attrs), format_defaults.text_size); format->character_spacing = util::apply_visitor(extract_value<value_double>(feature,attrs), format_defaults.character_spacing); format->line_spacing = util::apply_visitor(extract_value<value_double>(feature,attrs), format_defaults.line_spacing); format->text_opacity = util::apply_visitor(extract_value<value_double>(feature,attrs), format_defaults.text_opacity); format->halo_opacity = util::apply_visitor(extract_value<value_double>(feature,attrs), format_defaults.halo_opacity); format->halo_radius = util::apply_visitor(extract_value<value_double>(feature,attrs), format_defaults.halo_radius); format->fill = util::apply_visitor(extract_value<color>(feature,attrs), format_defaults.fill); format->halo_fill = util::apply_visitor(extract_value<color>(feature,attrs), format_defaults.halo_fill); format->text_transform = util::apply_visitor(extract_value<text_transform_enum>(feature,attrs), format_defaults.text_transform); format->face_name = format_defaults.face_name; format->fontset = format_defaults.fontset; tree_->apply(format, feature, attrs, output); } else MAPNIK_LOG_WARN(text_properties) << "text_symbolizer_properties can't produce text: No formatting tree!"; }
void format_node::apply(evaluated_format_properties_ptr const& p, feature_impl const& feature, attributes const& attrs, text_layout &output) const { evaluated_format_properties_ptr & new_properties = output.new_child_format_ptr(p); if (text_size) new_properties->text_size = util::apply_visitor(extract_value<value_double>(feature,attrs), *text_size); if (character_spacing) new_properties->character_spacing = util::apply_visitor(extract_value<value_double>(feature,attrs), *character_spacing); if (line_spacing) new_properties->line_spacing = util::apply_visitor(extract_value<value_double>(feature,attrs), *line_spacing); if (text_opacity) new_properties->text_opacity = util::apply_visitor(extract_value<value_double>(feature,attrs), *text_opacity); if (halo_radius) new_properties->halo_radius = util::apply_visitor(extract_value<value_double>(feature,attrs), *halo_radius); if (fill) new_properties->fill = util::apply_visitor(extract_value<color>(feature,attrs), *fill); if (halo_fill) new_properties->halo_fill = util::apply_visitor(extract_value<color>(feature,attrs), *halo_fill); if (text_transform) new_properties->text_transform = util::apply_visitor(extract_value<text_transform_enum>(feature,attrs), *text_transform); if (ff_settings) new_properties->ff_settings = util::apply_visitor(extract_value<font_feature_settings>(feature,attrs), *ff_settings); if (fontset) { new_properties->fontset = *fontset; } else { if (face_name) { new_properties->face_name = *face_name; new_properties->fontset.reset(); } } if (child_) child_->apply(new_properties, feature, attrs, output); else MAPNIK_LOG_WARN(format) << "Useless format: No text to format"; }
void text_symbolizer_properties::process(text_layout &output, feature_impl const& feature) const { output.clear(); if (tree_) { tree_->apply(format, feature, output); } else { MAPNIK_LOG_WARN(text_properties) << "text_symbolizer_properties can't produce text: No formatting tree!"; } }
void layout_node::apply(evaluated_format_properties_ptr const& p, feature_impl const& feature, attributes const& vars, text_layout & parent) const { text_layout_properties new_properties(parent.get_layout_properties()); if (dx) new_properties.dx = *dx; if (dy) new_properties.dy = *dy; if (text_ratio) new_properties.text_ratio = *text_ratio; if (wrap_width) new_properties.wrap_width = *wrap_width; if (wrap_char) new_properties.wrap_char = *wrap_char; if (wrap_before) new_properties.wrap_before = *wrap_before; if (repeat_wrap_char) new_properties.repeat_wrap_char = *repeat_wrap_char; if (rotate_displacement) new_properties.rotate_displacement = *rotate_displacement; if (orientation) new_properties.orientation = *orientation; if (halign) new_properties.halign = *halign; if (valign) new_properties.valign = *valign; if (jalign) new_properties.jalign = *jalign; // starting a new offset child with the new displacement value // we pass a null format tree since this is not the parent but a child text_layout_ptr child_layout = std::make_unique<text_layout>(parent.get_font_manager(), feature, vars, parent.get_scale_factor(), parent.get_default_text_properties(), new_properties, formatting::node_ptr()); // process contained format tree into the child node if (child_) { child_->apply(p, feature, vars, *child_layout); } else { MAPNIK_LOG_WARN(format) << "Useless layout node: Contains no text"; } parent.add_child(std::move(child_layout)); }
void text_node::apply(evaluated_format_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const { mapnik::value_unicode_string text_str = util::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *text_).to_unicode(); if (p->text_transform == UPPERCASE) { text_str = text_str.toUpper(); } else if (p->text_transform == LOWERCASE) { text_str = text_str.toLower(); } #if !UCONFIG_NO_BREAK_ITERATION else if (p->text_transform == CAPITALIZE) { // note: requires BreakIterator support in ICU which is optional text_str = text_str.toTitle(nullptr); } #endif if (text_str.length() > 0) { output.add_text(text_str, p); } }