double _rsvg_css_normalize_length (const RsvgLength * in, RsvgDrawingCtx * ctx, char dir) { if (in->factor == '\0') return in->length; else if (in->factor == 'p') { if (dir == 'h') return in->length * ctx->vb.rect.width; if (dir == 'v') return in->length * ctx->vb.rect.height; if (dir == 'o') return in->length * rsvg_viewport_percentage (ctx->vb.rect.width, ctx->vb.rect.height); } else if (in->factor == 'm' || in->factor == 'x') { double font = _rsvg_css_normalize_font_size (rsvg_current_state (ctx), ctx); if (in->factor == 'm') return in->length * font; else return in->length * font / 2.; } else if (in->factor == 'i') { if (dir == 'h') return in->length * ctx->dpi_x; if (dir == 'v') return in->length * ctx->dpi_y; if (dir == 'o') return in->length * rsvg_viewport_percentage (ctx->dpi_x, ctx->dpi_y); } else if (in->factor == 'l') { /* todo: "larger" */ } else if (in->factor == 's') { /* todo: "smaller" */ } return 0; }
double _rsvg_css_normalize_font_size (RsvgState * state, RsvgDrawingCtx * ctx) { RsvgState *parent; switch (state->font_size.factor) { case 'p': case 'm': case 'x': parent= rsvg_state_parent (state); if (parent) { double parent_size; parent_size = _rsvg_css_normalize_font_size (parent, ctx); return state->font_size.length * parent_size; } break; default: return _rsvg_css_normalize_length (&state->font_size, ctx, 'v'); break; } return 12.; }
static PangoLayout * rsvg_text_create_layout (RsvgDrawingCtx * ctx, RsvgState * state, const char *text, PangoContext * context) { PangoFontDescription *font_desc; PangoLayout *layout; PangoAttrList *attr_list; PangoAttribute *attribute; if (state->lang) pango_context_set_language (context, pango_language_from_string (state->lang)); if (state->unicode_bidi == UNICODE_BIDI_OVERRIDE || state->unicode_bidi == UNICODE_BIDI_EMBED) pango_context_set_base_dir (context, state->text_dir); font_desc = pango_font_description_copy (pango_context_get_font_description (context)); if (state->font_family) pango_font_description_set_family_static (font_desc, state->font_family); pango_font_description_set_style (font_desc, state->font_style); pango_font_description_set_variant (font_desc, state->font_variant); pango_font_description_set_weight (font_desc, state->font_weight); pango_font_description_set_stretch (font_desc, state->font_stretch); pango_font_description_set_size (font_desc, _rsvg_css_normalize_font_size (state, ctx) * PANGO_SCALE / ctx->dpi_y * 72); layout = pango_layout_new (context); pango_layout_set_font_description (layout, font_desc); pango_font_description_free (font_desc); attr_list = pango_attr_list_new (); attribute = pango_attr_letter_spacing_new (_rsvg_css_normalize_length (&state->letter_spacing, ctx, 'h') * PANGO_SCALE); attribute->start_index = 0; attribute->end_index = G_MAXINT; pango_attr_list_insert (attr_list, attribute); if (state->has_font_decor && text) { if (state->font_decor & TEXT_UNDERLINE) { attribute = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); attribute->start_index = 0; attribute->end_index = -1; pango_attr_list_insert (attr_list, attribute); } if (state->font_decor & TEXT_STRIKE) { attribute = pango_attr_strikethrough_new (TRUE); attribute->start_index = 0; attribute->end_index = -1; pango_attr_list_insert (attr_list, attribute); } } pango_layout_set_attributes (layout, attr_list); pango_attr_list_unref (attr_list); if (text) pango_layout_set_text (layout, text, -1); else pango_layout_set_text (layout, NULL, 0); pango_layout_set_alignment (layout, (state->text_dir == PANGO_DIRECTION_LTR || state->text_dir == PANGO_DIRECTION_TTB_LTR) ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT); return layout; }