TextStyle::Parameters TextStyleBuilder::applyRule(const DrawRule& _rule, const Properties& _props, bool _iconText) const { const static std::string defaultWeight("400"); const static std::string defaultStyle("normal"); const static std::string defaultFamily("default"); TextStyle::Parameters p; _rule.get(StyleParamKey::text_source, p.text); if (!_rule.isJSFunction(StyleParamKey::text_source)) { if (p.text.empty()) { p.text = _props.getString(key_name); } else { p.text = resolveTextSource(p.text, _props); } } if (p.text.empty()) { return p; } auto fontFamily = _rule.get<std::string>(StyleParamKey::text_font_family); fontFamily = (!fontFamily) ? &defaultFamily : fontFamily; auto fontWeight = _rule.get<std::string>(StyleParamKey::text_font_weight); fontWeight = (!fontWeight) ? &defaultWeight : fontWeight; auto fontStyle = _rule.get<std::string>(StyleParamKey::text_font_style); fontStyle = (!fontStyle) ? &defaultStyle : fontStyle; _rule.get(StyleParamKey::text_font_size, p.fontSize); p.fontSize *= m_style.pixelScale(); p.font = m_style.context()->getFont(*fontFamily, *fontStyle, *fontWeight, p.fontSize); _rule.get(StyleParamKey::text_font_fill, p.fill); _rule.get(StyleParamKey::text_font_stroke_color, p.strokeColor); _rule.get(StyleParamKey::text_font_stroke_width, p.strokeWidth); p.strokeWidth *= m_style.pixelScale(); _rule.get(StyleParamKey::transition_hide_time, p.labelOptions.hideTransition.time); _rule.get(StyleParamKey::transition_selected_time, p.labelOptions.selectTransition.time); _rule.get(StyleParamKey::transition_show_time, p.labelOptions.showTransition.time); uint32_t priority; if (_iconText) { if (_rule.get(StyleParamKey::text_priority, priority)) { p.labelOptions.priority = (float)priority; } _rule.get(StyleParamKey::text_collide, p.labelOptions.collide); _rule.get(StyleParamKey::text_interactive, p.interactive); _rule.get(StyleParamKey::text_offset, p.labelOptions.offset); p.labelOptions.offset *= m_style.pixelScale(); _rule.get(StyleParamKey::text_anchor, p.labelOptions.anchors); if (p.labelOptions.anchors.count == 0) { p.labelOptions.anchors.anchor = { LabelProperty::Anchor::bottom, LabelProperty::Anchor::top, LabelProperty::Anchor::right, LabelProperty::Anchor::left }; p.labelOptions.anchors.count = 4; } _rule.get(StyleParamKey::text_transition_hide_time, p.labelOptions.hideTransition.time); _rule.get(StyleParamKey::text_transition_selected_time, p.labelOptions.selectTransition.time); _rule.get(StyleParamKey::text_transition_show_time, p.labelOptions.showTransition.time); } else { if (_rule.get(StyleParamKey::priority, priority)) { p.labelOptions.priority = (float)priority; } _rule.get(StyleParamKey::collide, p.labelOptions.collide); _rule.get(StyleParamKey::interactive, p.interactive); _rule.get(StyleParamKey::offset, p.labelOptions.offset); p.labelOptions.offset *= m_style.pixelScale(); _rule.get(StyleParamKey::anchor, p.labelOptions.anchors); if (p.labelOptions.anchors.count == 0) { p.labelOptions.anchors.anchor = { LabelProperty::Anchor::center }; p.labelOptions.anchors.count = 1; } } _rule.get(StyleParamKey::text_wrap, p.maxLineWidth); size_t repeatGroupHash = 0; std::string repeatGroup; if (_rule.get(StyleParamKey::text_repeat_group, repeatGroup)) { hash_combine(repeatGroupHash, repeatGroup); } else { repeatGroupHash = _rule.getParamSetHash(); } StyleParam::Width repeatDistance; if (_rule.get(StyleParamKey::text_repeat_distance, repeatDistance)) { p.labelOptions.repeatDistance = repeatDistance.value; } else { p.labelOptions.repeatDistance = View::s_pixelsPerTile; } hash_combine(repeatGroupHash, p.text); p.labelOptions.repeatGroup = repeatGroupHash; p.labelOptions.repeatDistance *= m_style.pixelScale(); if (p.interactive) { // TODO optimization: for icon-text use the parent's properties p.labelOptions.properties = std::make_shared<Properties>(_props); } if (auto* transform = _rule.get<std::string>(StyleParamKey::text_transform)) { TextLabelProperty::transform(*transform, p.transform); } if (auto* align = _rule.get<std::string>(StyleParamKey::text_align)) { bool res = TextLabelProperty::align(*align, p.align); if (!res && p.labelOptions.anchors.count > 0) { p.align = TextLabelProperty::alignFromAnchor(p.labelOptions.anchors[0]); } } _rule.get(StyleParamKey::text_required, p.labelOptions.required); // TODO style option? p.labelOptions.buffer = p.fontSize * 0.25f; std::hash<TextStyle::Parameters> hash; p.labelOptions.paramHash = hash(p); p.lineSpacing = 2 * m_style.pixelScale(); return p; }