Ejemplo n.º 1
0
bool wxStaticText::SetFont( const wxFont &font )
{
    const bool wasUnderlined = GetFont().GetUnderlined();
    const bool wasStrickenThrough = GetFont().GetStrikethrough();

    bool ret = wxControl::SetFont(font);

    const bool isUnderlined = GetFont().GetUnderlined();
    const bool isStrickenThrough = GetFont().GetStrikethrough();

    if ( (isUnderlined != wasUnderlined) ||
            (isStrickenThrough != wasStrickenThrough) )
    {
        // We need to update the Pango attributes used for the text.
        if ( isUnderlined || isStrickenThrough )
        {
            PangoAttrList* const attrs = pango_attr_list_new();
            if ( isUnderlined )
            {
                PangoAttribute *a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
                a->start_index = 0;
                a->end_index = (guint)-1;
                pango_attr_list_insert(attrs, a);
            }

            if ( isStrickenThrough )
            {
                PangoAttribute *a = pango_attr_strikethrough_new( TRUE );
                a->start_index = 0;
                a->end_index = (guint) -1;
                pango_attr_list_insert(attrs, a);
            }

            gtk_label_set_attributes(GTK_LABEL(m_widget), attrs);
            pango_attr_list_unref(attrs);
        }
        else // No special attributes any more.
        {
            // Just remove any attributes we had set.
            gtk_label_set_attributes(GTK_LABEL(m_widget), NULL);
        }

        // The underlines for mnemonics are incompatible with using attributes
        // so turn them off when setting underlined font.
        gtk_label_set_use_underline(GTK_LABEL(m_widget), !isUnderlined);
    }

    // adjust the label size to the new label unless disabled
    if (!HasFlag(wxST_NO_AUTORESIZE))
    {
        SetSize( GetBestSize() );
    }
    return ret;
}
Ejemplo n.º 2
0
/**
 * _st_set_text_from_style:
 * @text: Target #ClutterText
 * @theme_node: Source #StThemeNode
 *
 * Set various GObject properties of the @text object using
 * CSS information from @theme_node.
 */
void
_st_set_text_from_style (ClutterText *text,
                         StThemeNode *theme_node)
{

    ClutterColor color;
    StTextDecoration decoration;
    PangoAttrList *attribs = NULL;
    const PangoFontDescription *font;
    StTextAlign align;

    st_theme_node_get_foreground_color (theme_node, &color);
    clutter_text_set_color (text, &color);

    font = st_theme_node_get_font (theme_node);
    clutter_text_set_font_description (text, (PangoFontDescription *) font);

    decoration = st_theme_node_get_text_decoration (theme_node);
    if (decoration)
    {
        attribs = pango_attr_list_new ();

        if (decoration & ST_TEXT_DECORATION_UNDERLINE)
        {
            PangoAttribute *underline = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
            pango_attr_list_insert (attribs, underline);
        }
        if (decoration & ST_TEXT_DECORATION_LINE_THROUGH)
        {
            PangoAttribute *strikethrough = pango_attr_strikethrough_new (TRUE);
            pango_attr_list_insert (attribs, strikethrough);
        }
        /* Pango doesn't have an equivalent attribute for _OVERLINE, and we deliberately
         * skip BLINK (for now...)
         */
    }

    clutter_text_set_attributes (text, attribs);

    if (attribs)
        pango_attr_list_unref (attribs);

    align = st_theme_node_get_text_align (theme_node);
    if (align == ST_TEXT_ALIGN_JUSTIFY)
    {
        clutter_text_set_justify (text, TRUE);
        clutter_text_set_line_alignment (text, PANGO_ALIGN_LEFT);
    }
    else
    {
        clutter_text_set_justify (text, FALSE);
        clutter_text_set_line_alignment (text, (PangoAlignment) align);
    }
}
Ejemplo n.º 3
0
Archivo: cdgdk.c Proyecto: LuaDist/cd
static int cdfont(cdCtxCanvas *ctxcanvas, const char *typeface, int style, int size)
{
  int is_italic = 0, is_bold = 0;   /* default is CD_PLAIN */
  int is_strikeout = 0, is_underline = 0;
  char font[256];
  PangoAttrList *attrs;

  if (cdStrEqualNoCase(typeface, "Courier") || cdStrEqualNoCase(typeface, "Courier New"))
    typeface = "Monospace";
  else if (cdStrEqualNoCase(typeface, "Times") || cdStrEqualNoCase(typeface, "Times New Roman"))
    typeface = "Serif";
  else if (cdStrEqualNoCase(typeface, "Helvetica") || cdStrEqualNoCase(typeface, "Arial"))
    typeface = "Sans";

  if (style & CD_BOLD)
    is_bold = 1;

  if (style & CD_ITALIC)
    is_italic = 1;

  if (style & CD_UNDERLINE)
    is_underline = 1;

  if (style & CD_STRIKEOUT)
    is_strikeout = 1;

  size = cdGetFontSizePoints(ctxcanvas->canvas, size);

  sprintf(font, "%s, %s%s%d", typeface, is_bold?"Bold ":"", is_italic?"Italic ":"", size);

  if (ctxcanvas->fontdesc) 
    pango_font_description_free(ctxcanvas->fontdesc);

  ctxcanvas->fontdesc = pango_font_description_from_string(font);

  if (!ctxcanvas->fontdesc)
    return 0;

  if (ctxcanvas->fontlayout)  
    g_object_unref(ctxcanvas->fontlayout);

  ctxcanvas->fontlayout = pango_layout_new(ctxcanvas->fontcontext);
  pango_layout_set_font_description(ctxcanvas->fontlayout, ctxcanvas->fontdesc);

  attrs = pango_attr_list_new();
  pango_attr_list_insert(attrs, pango_attribute_copy(pango_attr_strikethrough_new(is_strikeout ? TRUE : FALSE)));
  pango_attr_list_insert(attrs, pango_attribute_copy(pango_attr_underline_new(is_underline ? PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE)));
  pango_layout_set_attributes(ctxcanvas->fontlayout, attrs);

  pango_attr_list_unref(attrs);

  return 1;
}
Ejemplo n.º 4
0
static gboolean
s_parse_func        (MarkupData            *md,
		     OpenTag               *tag,
		     const gchar          **names,
		     const gchar          **values,
		     GMarkupParseContext   *context,
		     GError               **error)
{
  CHECK_NO_ATTRS("s");
  add_attribute (tag, pango_attr_strikethrough_new (TRUE));

  return TRUE;
}
Ejemplo n.º 5
0
// Although we don't use this function yet, but we must create it here.
// first, for the prepare the unicode drawing support in wxUniv/x11 port.
// If we use pango to draw the text, then we must set some attributes
// for pango layout, such as "strikethrough" and "underline".
bool wxFont::SetPangoAttrs(PangoLayout* layout) const
{
    if ( !IsOk() || !(GetUnderlined() || GetStrikethrough()) )
        return false;

    PangoAttrList* attrs = pango_attr_list_new();
    PangoAttribute* a;

    if ( GetUnderlined() )
    {
        a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
        pango_attr_list_insert(attrs, a);
    }
    if ( GetStrikethrough() )
    {
        a = pango_attr_strikethrough_new(true);
        pango_attr_list_insert(attrs, a);
    }

    pango_layout_set_attributes(layout, attrs);
    pango_attr_list_unref(attrs);

    return true;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
/* 
 * This function is used by gail_text_cell_get_offset_at_point()
 * and gail_text_cell_get_character_extents(). There is no 
 * cached PangoLayout for gailtextcell so we must create a temporary
 * one using this function.
 */ 
static PangoLayout*
create_pango_layout(GtkCellRendererText *gtk_renderer,
                    GtkWidget           *widget)
{
  PangoAttrList *attr_list;
  PangoLayout *layout;
  PangoUnderline uline;
  PangoFontMask mask;

  layout = gtk_widget_create_pango_layout (widget, gtk_renderer->text);

  if (gtk_renderer->extra_attrs)
    attr_list = pango_attr_list_copy (gtk_renderer->extra_attrs);
  else
    attr_list = pango_attr_list_new ();

  if (gtk_renderer->foreground_set)
    {
      PangoColor color;
      color = gtk_renderer->foreground;
      add_attr (attr_list, pango_attr_foreground_new (color.red,
                                                      color.green, color.blue));
    }

  if (gtk_renderer->strikethrough_set)
    add_attr (attr_list,
              pango_attr_strikethrough_new (gtk_renderer->strikethrough));

  mask = pango_font_description_get_set_fields (gtk_renderer->font);

  if (mask & PANGO_FONT_MASK_FAMILY)
    add_attr (attr_list,
      pango_attr_family_new (pango_font_description_get_family (gtk_renderer->font)));

  if (mask & PANGO_FONT_MASK_STYLE)
    add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (gtk_renderer->font)));

  if (mask & PANGO_FONT_MASK_VARIANT)
    add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (gtk_renderer->font)));

  if (mask & PANGO_FONT_MASK_WEIGHT)
    add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (gtk_renderer->font)));

  if (mask & PANGO_FONT_MASK_STRETCH)
    add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (gtk_renderer->font)));

  if (mask & PANGO_FONT_MASK_SIZE)
    add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (gtk_renderer->font)));

  if (gtk_renderer->scale_set &&
      gtk_renderer->font_scale != 1.0)
    add_attr (attr_list, pango_attr_scale_new (gtk_renderer->font_scale));

  if (gtk_renderer->underline_set)
    uline = gtk_renderer->underline_style;
  else
    uline = PANGO_UNDERLINE_NONE;

  if (uline != PANGO_UNDERLINE_NONE)
    add_attr (attr_list,
      pango_attr_underline_new (gtk_renderer->underline_style));

  if (gtk_renderer->rise_set)
    add_attr (attr_list, pango_attr_rise_new (gtk_renderer->rise));

  pango_layout_set_attributes (layout, attr_list);
  pango_layout_set_width (layout, -1);
  pango_attr_list_unref (attr_list);

  return layout;
}
			void GuiSolidLabelElementRenderer::OnElementStateChanged()
			{
				FontProperties font = element->GetFont();
				Color color = element->GetColor();
				int layoutWidth, layoutHeight;
				
				AString family = wtoa(font.fontFamily);
				pango_font_description_set_family(pangoFontDesc, family.Buffer());
				pango_font_description_set_absolute_size(pangoFontDesc, font.size * PANGO_SCALE);

				if(font.italic) pango_font_description_set_style(pangoFontDesc, PANGO_STYLE_ITALIC);
				else pango_font_description_set_style(pangoFontDesc, PANGO_STYLE_NORMAL);

				if(attrList)
				{
					pango_attr_list_unref(attrList);
				}

				attrList = pango_attr_list_new();
				
				pango_attr_list_insert(attrList, pango_attr_underline_new(
							font.underline ? PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE)
					);

				pango_attr_list_insert(attrList, pango_attr_strikethrough_new (
							font.strikeline ? TRUE : FALSE
							)
						);

				pango_attr_list_insert(attrList, pango_attr_weight_new (
							font.bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_MEDIUM
							)
						);

				if(layout)
				{
					g_object_unref(layout);
					layout = NULL;
				}

				if(cairoContext)
				{
					layout = pango_cairo_create_layout(cairoContext);

					WString wtext = (font.fontFamily == L"Webdings") ? helpers::WebdingsMap(element->GetText()) : element->GetText();
					AString text = wtoa(wtext);

					pango_layout_set_font_description(layout, pangoFontDesc);
					pango_layout_set_attributes(layout, attrList);
					pango_layout_set_text(layout, text.Buffer(), text.Length());
					pango_layout_set_alignment(layout, 
							element->GetHorizontalAlignment() == Alignment::Left ? PANGO_ALIGN_LEFT :
							element->GetHorizontalAlignment() == Alignment::Center ? PANGO_ALIGN_CENTER :
							element->GetHorizontalAlignment() == Alignment::Right ? PANGO_ALIGN_RIGHT :
							PANGO_ALIGN_LEFT
							);


					pango_cairo_update_layout(cairoContext, layout);


					pango_layout_get_pixel_size( layout, &layoutWidth, &layoutHeight);

					minSize.x = layoutWidth;
					minSize.y = layoutHeight;
				}
			}
Ejemplo n.º 9
0
bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const
{
    if (!IsOk() || !(GetUnderlined() || GetStrikethrough()))
        return false;

    PangoAttrList* attrs = pango_attr_list_new();
    PangoAttribute* a;

    if (wx_pango_version_check(1,16,0))
    {
        // a PangoLayout which has leading/trailing spaces with underlined font
        // is not correctly drawn by this pango version: Pango won't underline the spaces.
        // This can be a problem; e.g. wxHTML rendering of underlined text relies on
        // this behaviour. To workaround this problem, we use a special hack here
        // suggested by pango maintainer Behdad Esfahbod: we prepend and append two
        // empty space characters and give them a dummy colour attribute.
        // This will force Pango to underline the leading/trailing spaces, too.

        const char* text = pango_layout_get_text(layout);
        const size_t n = strlen(text);
        if ((n > 0 && text[0] == ' ') || (n > 1 && text[n - 1] == ' '))
        {
            wxCharBuffer buf(n + 6);
            // copy the leading U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format
            memcpy(buf.data(), "\342\200\214", 3);
            // copy the user string
            memcpy(buf.data() + 3, text, n);
            // copy the trailing U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format
            memcpy(buf.data() + 3 + n, "\342\200\214", 3);

            pango_layout_set_text(layout, buf, n + 6);

            // Add dummy attributes (use colour as it's invisible anyhow for 0
            // width spaces) to ensure that the spaces in the beginning/end of the
            // string are underlined too.
            a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614);
            a->start_index = 0;
            a->end_index = 3;
            pango_attr_list_insert(attrs, a);

            a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614);
            a->start_index = n + 3;
            a->end_index = n + 6;
            pango_attr_list_insert(attrs, a);
        }
    }
    if (GetUnderlined())
    {
        a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
        pango_attr_list_insert(attrs, a);
    }
    if (GetStrikethrough())
    {
        a = pango_attr_strikethrough_new(true);
        pango_attr_list_insert(attrs, a);
    }

    pango_layout_set_attributes(layout, attrs);
    pango_attr_list_unref(attrs);

    return true;
}
Ejemplo n.º 10
0
static IgtkFont* gtkFindFont(const char *standardfont)
{
  PangoFontMetrics* metrics;
  PangoFontDescription* fontdesc;
  int i, 
      is_underline = 0,
      is_strikeout = 0,
      count = iupArrayCount(gtk_fonts);

  IgtkFont* fonts = (IgtkFont*)iupArrayGetData(gtk_fonts);

  /* Check if the standardfont already exists in cache */
  for (i = 0; i < count; i++)
  {
    if (iupStrEqualNoCase(standardfont, fonts[i].standardfont))
      return &fonts[i];
  }

  /* not found, create a new one */
  {
    int size;
    int is_bold = 0,
      is_italic = 0;
    char typeface[1024];
    char *new_standardfont = NULL;
    const char* mapped_name;

    if (!iupFontParsePango(standardfont, typeface, &size, &is_bold, &is_italic, &is_underline, &is_strikeout))
      return NULL;

    mapped_name = iupFontGetPangoName(typeface);
    if (mapped_name)
      strcpy(typeface, mapped_name);

    if (is_underline || is_strikeout || size<0)
      new_standardfont = iupStrDup(standardfont);

    if (is_underline)
    {
      char* under = strstr(standardfont, "Underline");
      int len = strlen(standardfont);
      int len1 = (size_t)(under-standardfont);
      memcpy(new_standardfont, standardfont, len1);
      memcpy(new_standardfont+len1, under+9+1, len-len1-9+1); /* strlen("Underline") */
      standardfont = new_standardfont;
    }

    if (is_strikeout)
    {
      char* strike = strstr(standardfont, "Strikeout");
      int len = strlen(standardfont);
      int len1 = (size_t)(strike-standardfont);
      memcpy(new_standardfont, standardfont, len1);
      memcpy(new_standardfont+len1, strike+9+1, len-len1-9+1); /* strlen("Strikeout") */
      standardfont = new_standardfont;
    }

    if (size<0)
    {
      double res;
      int len1, len2;
      char *sz, size_str[10];
      sprintf(size_str, "%d", size);
      sz = strstr(standardfont, size_str);
      len1 = (size_t)(sz-standardfont);

      res = ((double)gdk_screen_get_width(gdk_screen_get_default()) / (double)gdk_screen_get_width_mm(gdk_screen_get_default())); /* pixels/mm */
      /* 1 point = 1/72 inch     1 inch = 25.4 mm */
      /* pixel = ((point/72)*25.4)*pixel/mm */
      size = (int)((-size/res)*2.83464567 + 0.5); /* from pixels to points */

      len2 = sprintf(size_str, "%d", size);

      memcpy(new_standardfont, standardfont, len1);
      memcpy(new_standardfont+len1, size_str, len2+1);
    }

    fontdesc = pango_font_description_from_string(standardfont);

    if (new_standardfont) free(new_standardfont);
  }

  if (!fontdesc) 
    return NULL;

  /* create room in the array */
  fonts = (IgtkFont*)iupArrayInc(gtk_fonts);

  strcpy(fonts[i].standardfont, standardfont);
  fonts[i].fontdesc = fontdesc;
  fonts[i].strikethrough = pango_attr_strikethrough_new(is_strikeout? TRUE: FALSE);
  fonts[i].underline = pango_attr_underline_new(is_underline? PANGO_UNDERLINE_SINGLE: PANGO_UNDERLINE_NONE);
  fonts[i].layout = pango_layout_new(gtk_fonts_context);

  metrics = pango_context_get_metrics(gtk_fonts_context, fontdesc, pango_context_get_language(gtk_fonts_context));
  fonts[i].charheight = pango_font_metrics_get_ascent(metrics) + pango_font_metrics_get_descent(metrics);
  fonts[i].charheight = IUPGTK_PANGOUNITS2PIXELS(fonts[i].charheight);
  fonts[i].charwidth = pango_font_metrics_get_approximate_char_width(metrics);
  fonts[i].charwidth = IUPGTK_PANGOUNITS2PIXELS(fonts[i].charwidth);
  pango_font_metrics_unref(metrics); 

  gtkFontUpdate(&(fonts[i]));

  return &fonts[i];
}
Ejemplo n.º 11
0
PangoLayout*
gdip_pango_setup_layout (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font,
	GDIPCONST RectF *rc, RectF *box, GDIPCONST GpStringFormat *format, int **charsRemoved)
{
	GpStringFormat *fmt;
	PangoLayout *layout;
	PangoContext *context;
	PangoRectangle logical;   /* logical size of text (used for alignment) */
	PangoRectangle ink;       /* ink size of text (to pixel boundaries) */
	PangoAttrList *list = NULL;
	GString *ftext;
	PangoTabArray *tabs;
	PangoLayoutIter *iter;
	int i;
	int FrameWidth;     /* rc->Width (or rc->Height if vertical) */
	int FrameHeight;    /* rc->Height (or rc->Width if vertical) */
	int FrameX;         /* rc->X (or rc->Y if vertical) */
	int FrameY;         /* rc->Y (or rc->X if vertical) */
	int y0;             /* y0,y1,clipNN used for checking line positions vs. clip rectangle */
	int y1;
	double clipx1;
	double clipx2;
	double clipy1;
	double clipy2;
	int trimSpace;      /* whether or not to trim the space */

	gchar *text = ucs2_to_utf8 (stringUnicode, length);
	if (!text)
		return NULL;
	length = strlen(text);

	if (charsRemoved) {
		(*charsRemoved) = GdipAlloc (sizeof (int) * length);
		if (!*charsRemoved) {
			GdipFree (text);
		return NULL;
		}
		memset (*charsRemoved, 0, sizeof (int) * length);
	}

	/* TODO - Digit substitution */

// g_warning ("layout >%s< (%d) [x %g, y %g, w %g, h %g] [font %s, %g points]", text, length, rc->X, rc->Y, rc->Width, FrameHeight, font->face, font->emSize);

	/* a NULL format is valid, it means get the generic default values (and free them later) */
	if (!format) {
		GpStatus status = GdipStringFormatGetGenericDefault ((GpStringFormat **)&fmt);
		if (status != Ok) {
			GdipFree (text);
			return NULL;
		}
	} else {
		fmt = (GpStringFormat *)format;
	}

	layout = pango_cairo_create_layout (graphics->ct);

	/* context is owned by Pango (i.e. not referenced counted) do not free */
	context = pango_layout_get_context (layout);

	pango_layout_set_font_description (layout, gdip_get_pango_font_description ((GpFont*) font));

	if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
		FrameWidth = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Height));
		FrameHeight = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Width));
		FrameX = SAFE_FLOAT_TO_UINT32 (rc->Y);
		FrameY = SAFE_FLOAT_TO_UINT32 (rc->X);
	} else {
		FrameWidth = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Width));
		FrameHeight = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Height));
		FrameX = SAFE_FLOAT_TO_UINT32 (rc->X);
		FrameY = SAFE_FLOAT_TO_UINT32 (rc->Y);
	}
	//g_warning("FW: %d\tFH: %d", FrameWidth, FrameHeight);

	if ((FrameWidth <= 0) || (fmt->formatFlags & StringFormatFlagsNoWrap)) {
		pango_layout_set_width (layout, -1);
		//g_warning ("Setting width: %d", -1);
	} else {
		pango_layout_set_width (layout, FrameWidth * PANGO_SCALE);
		//g_warning ("Setting width: %d", FrameWidth * PANGO_SCALE);
	}

	if ((rc->Width != 0) && (rc->Height != 0) && ((fmt->formatFlags & StringFormatFlagsNoClip) == 0)) {
// g_warning ("\tclip [%g %g %g %g]", rc->X, rc->Y, rc->Width, rc->Height);
		/* We do not call cairo_reset_clip because we want to take previous clipping into account */
		/* Use rc instead of frame variables because this is pre-transform */
		gdip_cairo_rectangle (graphics, rc->X, rc->Y, rc->Width, rc->Height, TRUE);
		cairo_clip (graphics->ct);
	}

		/* with GDI+ the API not the renderer makes the direction decision */
		pango_layout_set_auto_dir (layout, FALSE);
	if (!(fmt->formatFlags & StringFormatFlagsDirectionRightToLeft) != !(fmt->formatFlags & StringFormatFlagsDirectionVertical)) {
		pango_context_set_base_dir (context, PANGO_DIRECTION_WEAK_RTL);
		pango_layout_context_changed (layout);

		/* horizontal alignment */
		switch (fmt->alignment) {
		case StringAlignmentNear:
			pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
			break;
		case StringAlignmentCenter:
			pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
			break;
		case StringAlignmentFar:
			pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
			break;
		}
	} else {
		/* pango default base dir is WEAK_LTR, which is what we want */

		/* horizontal alignment */
		switch (fmt->alignment) {
		case StringAlignmentNear:
			pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
			break;
		case StringAlignmentCenter:
			pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
			break;
		case StringAlignmentFar:
			pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
			break;
		}
	}

#ifdef PANGO_VERSION_CHECK
#if PANGO_VERSION_CHECK(1,16,0)
	if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
		if (fmt->formatFlags & StringFormatFlagsDirectionRightToLeft) {
			cairo_rotate (graphics->ct, M_PI/2.0);
			cairo_translate (graphics->ct, 0, -FrameHeight);
			pango_cairo_update_context (graphics->ct, context);
		} else {
			cairo_rotate (graphics->ct, 3.0*M_PI/2.0);
			cairo_translate (graphics->ct, -FrameWidth, 0);
			pango_cairo_update_context (graphics->ct, context);
		}
		/* only since Pango 1.16 */
		pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO);
		pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_LINE);
		pango_layout_context_changed (layout);
	}
#endif
#endif

	/* TODO - StringFormatFlagsDisplayFormatControl
		scan and replace them ??? */

	/* Trimming options seem to apply only to the end of the string - gdi+ will still wrap
	 * with preference to word first, then character.  Unfortunately, pango doesn't have
	 * any way to differentiate wrapping behavior from trimming behavior that I could find */
	pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
	switch (fmt->trimming) {
	case StringTrimmingNone:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
		break;
	case StringTrimmingCharacter:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
		break;
	case StringTrimmingWord:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
		break;
	case StringTrimmingEllipsisCharacter:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
		if (!(fmt->formatFlags & StringFormatFlagsNoWrap))
			pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE);
		break;
	case StringTrimmingEllipsisWord:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
		if (!(fmt->formatFlags & StringFormatFlagsNoWrap))
			pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE);
		break;
	case StringTrimmingEllipsisPath:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_MIDDLE);
		if (!(fmt->formatFlags & StringFormatFlagsNoWrap))
			pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE);
		break;
	}

	/* some stuff can only be done by manipulating the attributes (but we can avoid this most of the time) */
	if ((fmt->formatFlags & StringFormatFlagsNoFontFallback) || (font->style & (FontStyleUnderline | FontStyleStrikeout))) {

		list = gdip_get_layout_attributes (layout);

		/* StringFormatFlagsNoFontFallback */
		if (fmt->formatFlags & StringFormatFlagsNoFontFallback) {
			PangoAttribute *attr = pango_attr_fallback_new (FALSE);
			attr->start_index = 0;
			attr->end_index = length;
			pango_attr_list_insert (list, attr);
		}

		if (font->style & FontStyleUnderline) {
			PangoAttribute *attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
			attr->start_index = 0;
			attr->end_index = length;
			pango_attr_list_insert (list, attr);
		}

		if (font->style & FontStyleStrikeout) {
			PangoAttribute *attr = pango_attr_strikethrough_new (TRUE);
			attr->start_index = 0;
			attr->end_index = length;
			pango_attr_list_insert (list, attr);
		}
	}

	if (fmt->numtabStops > 0) {
		float tabPosition;
		tabs = pango_tab_array_new (fmt->numtabStops, FALSE);
		tabPosition = fmt->firstTabOffset;
		for (i = 0; i < fmt->numtabStops; i++) {
			tabPosition += fmt->tabStops[i];
			pango_tab_array_set_tab (tabs, i, PANGO_TAB_LEFT, (gint)min (tabPosition, PANGO_MAX) * PANGO_SCALE);
		}
		pango_layout_set_tabs (layout, tabs);
		pango_tab_array_free (tabs);
	}

	//g_warning ("length before ws removal: %d", length);
	trimSpace = (fmt->formatFlags & StringFormatFlagsMeasureTrailingSpaces) == 0;
	switch (fmt->hotkeyPrefix) {
	case HotkeyPrefixHide:
		/* we need to remove any accelerator from the string */
		ftext = gdip_process_string (text, length, 1, trimSpace, NULL, charsRemoved);
		break;
	case HotkeyPrefixShow:
		/* optimization: is seems that we never see the hotkey when using an underline font */
		if (font->style & FontStyleUnderline) {
			/* so don't bother drawing it (and simply add the '&' character) */
			ftext = gdip_process_string (text, length, 1, trimSpace, NULL, charsRemoved);
		} else {
			/* find accelerator and add attribute to the next character (unless it's the prefix too) */
			if (!list)
				list = gdip_get_layout_attributes (layout);
			ftext = gdip_process_string (text, length, 1, trimSpace, list, charsRemoved);
		}
		break;
	default:
		ftext = gdip_process_string (text, length, 0, trimSpace, NULL, charsRemoved);
		break;
	}
	length = ftext->len;
	//g_warning ("length after ws removal: %d", length);

	if (list) {
		pango_layout_set_attributes (layout, list);
		pango_attr_list_unref (list);
	}

// g_warning("\tftext>%s< (%d)", ftext->str, -1);
	pango_layout_set_text (layout, ftext->str, ftext->len);
	GdipFree (text);
	g_string_free(ftext, TRUE);

	/* Trim the text after the last line for ease of counting lines/characters */
	/* Also prevents drawing whole lines outside the boundaries if NoClip was specified */
	/* In case of pre-existing clipping, use smaller of clip rectangle or our specified height */
	if (FrameHeight > 0) {
		cairo_clip_extents (graphics->ct, &clipx1, &clipy1, &clipx2, &clipy2);
		if (clipy2 > 0 && !(fmt->formatFlags & StringFormatFlagsNoClip))
			clipy2 = min (clipy2, FrameHeight + FrameY);
		else
			clipy2 = FrameHeight + FrameY;
		iter = pango_layout_get_iter (layout);
		do {
			if (iter == NULL)
				break;
			pango_layout_iter_get_line_yrange (iter, &y0, &y1);
			//g_warning("yrange: %d  %d  clipy2: %f", y0 / PANGO_SCALE, y1 / PANGO_SCALE, clipy2);
			/* StringFormatFlagsLineLimit */
			if (((fmt->formatFlags & StringFormatFlagsLineLimit) && y1 / PANGO_SCALE > clipy2) || (y0 / PANGO_SCALE > clipy2)) {
				PangoLayoutLine *line = pango_layout_iter_get_line_readonly (iter);
				pango_layout_set_text (layout, pango_layout_get_text (layout), line->start_index);
				break;
			}
		} while (pango_layout_iter_next_line (iter));
		pango_layout_iter_free (iter);
	}

	pango_layout_get_pixel_extents (layout, &ink, &logical);
// g_warning ("\tlogical\t[x %d, y %d, w %d, h %d][x %d, y %d, w %d, h %d]", logical.x, logical.y, logical.width, logical.height, ink.x, ink.y, ink.width, ink.height);

	if ((fmt->formatFlags & StringFormatFlagsNoFitBlackBox) == 0) {
		/* By default don't allow overhang - ink space may be larger than logical space */
		if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
			box->X = min (ink.y, logical.y);
			box->Y = min (ink.x, logical.x);
			box->Height = max (ink.width, logical.width);
			box->Width = max (ink.height, logical.height);
		} else {
			box->X = min (ink.x, logical.x);
			box->Y = min (ink.y, logical.y);
			box->Height = max (ink.height, logical.height);
			box->Width = max (ink.width, logical.width);
		}
	} else {
		/* Allow overhang */
		if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
			box->X = logical.y;
			box->Y = logical.x;
			box->Height = logical.width;
			box->Width = logical.height;
		} else {
			box->X = logical.x;
			box->Y = logical.y;
	box->Height = logical.height;
			box->Width = logical.width;
		}
	}
// g_warning ("\tbox\t[x %g, y %g, w %g, h %g]", box->X, box->Y, box->Width, box->Height);

	/* vertical alignment*/
	if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
		switch (fmt->lineAlignment) {
		case StringAlignmentNear:
			break;
		case StringAlignmentCenter:
			box->X += (rc->Width - box->Width) / 2;
			break;
		case StringAlignmentFar:
			box->X += (rc->Width - box->Width);
			break;
		}
	} else {
	switch (fmt->lineAlignment) {
	case StringAlignmentNear:
		break;
	case StringAlignmentCenter:
			box->Y += (rc->Height - box->Height) / 2;
		break;
	case StringAlignmentFar:
			box->Y += (rc->Height - box->Height);
		break;
	}
	}
// g_warning ("va-box\t[x %g, y %g, w %g, h %g]", box->X, box->Y, box->Width, box->Height);

	pango_cairo_update_layout (graphics->ct, layout);

	return layout;
}
Ejemplo n.º 12
0
static PangoLayout*
create_layout(HippoCanvasText *text,
              int              allocation_width)
{
    HippoCanvasBox *box = HIPPO_CANVAS_BOX(text);
    PangoLayout *layout;
    HippoCanvasStyle *style = hippo_canvas_context_get_style(HIPPO_CANVAS_CONTEXT(text));

    g_return_val_if_fail(box->context != NULL, NULL);
    
    layout = hippo_canvas_context_create_layout(box->context);

    if (box->font_desc) {
        PangoFontDescription *merged = pango_font_description_copy(hippo_canvas_style_get_font(style));
        pango_font_description_merge(merged, box->font_desc, TRUE);
        pango_layout_set_font_description(layout, merged);
        pango_font_description_free(merged);
    } else {
        pango_layout_set_font_description(layout, hippo_canvas_style_get_font(style));
    }
    
    {
        PangoAttrList *attrs;
        HippoTextDecoration decoration = hippo_canvas_style_get_text_decoration(style);
        
        if (text->attributes)
            attrs = pango_attr_list_copy(text->attributes);
        else
            attrs = pango_attr_list_new();

        
        if (ABS(1.0 - text->font_scale) > .000001) {
            PangoAttribute *attr = pango_attr_scale_new(text->font_scale);
            attr->start_index = 0;
            attr->end_index = G_MAXUINT;
            pango_attr_list_insert(attrs, attr);
        }

        if ((decoration & HIPPO_TEXT_DECORATION_UNDERLINE) != 0) {
            PangoAttribute *attr = pango_attr_underline_new(TRUE);
            attr->start_index = 0;
            attr->end_index = G_MAXUINT;
            pango_attr_list_insert(attrs, attr);
        }

        if ((decoration & HIPPO_TEXT_DECORATION_LINE_THROUGH) != 0) {
            PangoAttribute *attr = pango_attr_strikethrough_new(TRUE);
            attr->start_index = 0;
            attr->end_index = G_MAXUINT;
            pango_attr_list_insert(attrs, attr);
        }

        pango_layout_set_attributes(layout, attrs);
        pango_attr_list_unref(attrs);
    }
    
    if (text->text != NULL) {
        pango_layout_set_text(layout, text->text, -1);
    }

    if (allocation_width >= 0) {
        int layout_width, layout_height;
        pango_layout_get_size(layout, &layout_width, &layout_height);
        layout_width /= PANGO_SCALE;
        layout_height /= PANGO_SCALE;
        
        /* Force layout smaller if required, but we don't want to make
         * the layout _wider_ because it breaks alignment, so only do
         * this if required.
         */
        if (layout_width > allocation_width) {
            pango_layout_set_width(layout, allocation_width * PANGO_SCALE);

            /* If we set ellipsize, then it overrides wrapping. If we get
             * too-small allocation for HIPPO_CANVAS_SIZE_FULL_WIDTH, then
             * we want to ellipsize instead of wrapping.
             */
            if (text->size_mode == HIPPO_CANVAS_SIZE_WRAP_WORD) {
                pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
            } else {
                pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
            }

            /* For now if we say ellipsize end, we always just want one line.
             * Maybe this should be an orthogonal property?
             */
            if (text->size_mode == HIPPO_CANVAS_SIZE_ELLIPSIZE_END) {
                pango_layout_set_single_paragraph_mode(layout, TRUE);

                /* Pango's line separator character in this case is ugly, so we
                 * fix it. Not a very efficient approach, but oh well.
                 */
                if (text->text != NULL) {
                    char *new_text = remove_newlines(text->text);
                    /* avoid making the layout recompute everything
                     * if we didn't have newlines anyhow
                     */
                    if (strcmp(text->text, new_text) != 0) {
                        pango_layout_set_text(layout, new_text, -1);
                    }
                    g_free(new_text);
                }
            }
        }
    }
    
    return layout;
}
static PangoAttrList*
hildon_font_selection_dialog_create_attrlist    (HildonFontSelectionDialog *fontsel, 
                                                 guint start_index, 
                                                 guint len)
{
    PangoAttrList *list;
    PangoAttribute *attr;
    gint size, position;
    gboolean family_set, size_set, color_set, bold, bold_set,
             italic, italic_set, underline, underline_set,
             strikethrough, strikethrough_set, position_set;
    GdkColor *color = NULL;
    gchar *family = NULL;
    gdouble font_scaling = 1.0;

    list = pango_attr_list_new ();

    g_object_get (G_OBJECT (fontsel),
            "family", &family, "family-set", &family_set,
            "size", &size, "size-set", &size_set,
            "color", &color, "color-set", &color_set,
            "bold", &bold, "bold-set", &bold_set,
            "italic", &italic, "italic-set", &italic_set,
            "underline", &underline, "underline-set", &underline_set,
            "strikethrough", &strikethrough, "strikethrough-set", 
            &strikethrough_set, "position", &position, 
            "position-set", &position_set, 
            "font-scaling", &font_scaling,
            NULL);

    /* family */
    if (family_set)
    {
        attr = pango_attr_family_new (family);
        add_preview_text_attr (list, attr, start_index, len);
    }
    g_free (family);

    /* size */
    if (size_set)
    {
        attr = pango_attr_size_new (size * PANGO_SCALE);
        add_preview_text_attr (list, attr, start_index, len);
    }

    /*color*/
    if (color_set)
    {
        attr = pango_attr_foreground_new (color->red, color->green, color->blue);
        add_preview_text_attr (list, attr, start_index, len);
    }

    if (color != NULL)
        gdk_color_free (color);

    /*weight*/
    if (bold_set)
    {
        if (bold)
            attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
        else
            attr = pango_attr_weight_new (PANGO_WEIGHT_NORMAL);

        add_preview_text_attr(list, attr, start_index, len);
    }

    /* style */
    if (italic_set)
    {
        if (italic)
            attr = pango_attr_style_new (PANGO_STYLE_ITALIC);
        else
            attr = pango_attr_style_new (PANGO_STYLE_NORMAL);

        add_preview_text_attr(list, attr, start_index, len);
    }

    /* underline */
    if (underline_set)
    {
        if (underline)
            attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
        else
            attr = pango_attr_underline_new (PANGO_UNDERLINE_NONE);

        add_preview_text_attr(list, attr, start_index, len);
    }

    /* strikethrough */
    if (strikethrough_set)
    {
        if (strikethrough)
            attr = pango_attr_strikethrough_new (TRUE);
        else
            attr = pango_attr_strikethrough_new (FALSE);

        add_preview_text_attr(list, attr, start_index, len);
    }

    /* position */
    if (position_set)
    {
        switch (position)
        {
            case 1: /*super*/
                attr = pango_attr_rise_new (SUPERSCRIPT_RISE);
                break;
            case -1: /*sub*/
                attr = pango_attr_rise_new (SUBSCRIPT_LOW);
                break;
            default: /*normal*/
                attr = pango_attr_rise_new (0);
                break;
        }

        add_preview_text_attr (list, attr, start_index, len);
    }

    /* font scaling for preview */
    if (font_scaling)
    {
        attr = pango_attr_scale_new(font_scaling);
        add_preview_text_attr(list, attr, 0, len + start_index);
    }

    return list;
}
Ejemplo n.º 14
0
static gboolean
span_parse_func     (MarkupData            *md,
		     OpenTag               *tag,
		     const gchar          **names,
		     const gchar          **values,
		     GMarkupParseContext   *context,
		     GError               **error)
{
  int line_number, char_number;
  int i;

  const char *family = NULL;
  const char *size = NULL;
  const char *style = NULL;
  const char *weight = NULL;
  const char *variant = NULL;
  const char *stretch = NULL;
  const char *desc = NULL;
  const char *foreground = NULL;
  const char *background = NULL;
  const char *underline = NULL;
  const char *underline_color = NULL;
  const char *strikethrough = NULL;
  const char *strikethrough_color = NULL;
  const char *rise = NULL;
  const char *letter_spacing = NULL;
  const char *lang = NULL;
  const char *fallback = NULL;
  const char *gravity = NULL;
  const char *gravity_hint = NULL;

  g_markup_parse_context_get_position (context,
				       &line_number, &char_number);

#define CHECK_DUPLICATE(var) G_STMT_START{                              \
	  if ((var) != NULL) {                                          \
	    g_set_error (error, G_MARKUP_ERROR,                         \
			 G_MARKUP_ERROR_INVALID_CONTENT,                \
			 _("Attribute '%s' occurs twice on <span> tag " \
			   "on line %d char %d, may only occur once"),  \
			 names[i], line_number, char_number);           \
	    return FALSE;                                               \
	  }}G_STMT_END
#define CHECK_ATTRIBUTE2(var, name) \
	if (attr_strcmp (names[i], (name)) == 0) { \
	  CHECK_DUPLICATE (var); \
	  (var) = values[i]; \
	  found = TRUE; \
	  break; \
	}
#define CHECK_ATTRIBUTE(var) CHECK_ATTRIBUTE2 (var, G_STRINGIFY (var))

  i = 0;
  while (names[i])
    {
      gboolean found = FALSE;

      switch (names[i][0]) {
      case 'f':
	CHECK_ATTRIBUTE (fallback);
	CHECK_ATTRIBUTE2(desc, "font");
	CHECK_ATTRIBUTE2(desc, "font_desc");
	CHECK_ATTRIBUTE2(family, "face");

	CHECK_ATTRIBUTE2(family, "font_family");
	CHECK_ATTRIBUTE2(size, "font_size");
	CHECK_ATTRIBUTE2(stretch, "font_stretch");
	CHECK_ATTRIBUTE2(style, "font_style");
	CHECK_ATTRIBUTE2(variant, "font_variant");
	CHECK_ATTRIBUTE2(weight, "font_weight");

	CHECK_ATTRIBUTE (foreground);
	CHECK_ATTRIBUTE2 (foreground, "fgcolor");
	break;
      case 's':
	CHECK_ATTRIBUTE (size);
	CHECK_ATTRIBUTE (stretch);
	CHECK_ATTRIBUTE (strikethrough);
	CHECK_ATTRIBUTE (strikethrough_color);
	CHECK_ATTRIBUTE (style);
	break;
      case 'g':
	CHECK_ATTRIBUTE (gravity);
	CHECK_ATTRIBUTE (gravity_hint);
	break;
      case 'l':
	CHECK_ATTRIBUTE (lang);
	CHECK_ATTRIBUTE (letter_spacing);
	break;
      case 'u':
	CHECK_ATTRIBUTE (underline);
	CHECK_ATTRIBUTE (underline_color);
	break;
      default:
	CHECK_ATTRIBUTE (background);
	CHECK_ATTRIBUTE2 (background, "bgcolor");
	CHECK_ATTRIBUTE2(foreground, "color");
	CHECK_ATTRIBUTE (rise);
	CHECK_ATTRIBUTE (variant);
	CHECK_ATTRIBUTE (weight);
	break;
      }

      if (!found)
	{
	  g_set_error (error, G_MARKUP_ERROR,
		       G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
		       _("Attribute '%s' is not allowed on the <span> tag "
			 "on line %d char %d"),
		       names[i], line_number, char_number);
	  return FALSE;
	}

      ++i;
    }

  /* Parse desc first, then modify it with other font-related attributes. */
  if (G_UNLIKELY (desc))
    {
      PangoFontDescription *parsed;

      parsed = pango_font_description_from_string (desc);
      if (parsed)
	{
	  add_attribute (tag, pango_attr_font_desc_new (parsed));
	  if (tag)
	    open_tag_set_absolute_font_size (tag, pango_font_description_get_size (parsed));
	  pango_font_description_free (parsed);
	}
    }

  if (G_UNLIKELY (family))
    {
      add_attribute (tag, pango_attr_family_new (family));
    }

  if (G_UNLIKELY (size))
    {
      if (g_ascii_isdigit (*size))
	{
	  const char *end;
	  gint n;

/* cap size from the top at an arbitrary 2048 */
#define MAX_SIZE (2048 * PANGO_SCALE)

	  if ((end = size, !pango_scan_int (&end, &n)) || *end != '\0' || n < 0 || n > MAX_SIZE)
	    {
	      g_set_error (error,
			   G_MARKUP_ERROR,
			   G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Value of 'size' attribute on <span> tag on line %d "
			     "could not be parsed; should be an integer less than %d, or a "
			     "string such as 'small', not '%s'"),
			   line_number, MAX_SIZE+1, size);
	      goto error;
	    }

	  add_attribute (tag, pango_attr_size_new (n));
	  if (tag)
	    open_tag_set_absolute_font_size (tag, n);
	}
      else if (strcmp (size, "smaller") == 0)
	{
	  if (tag)
	    {
	      tag->scale_level_delta -= 1;
	      tag->scale_level -= 1;
	    }
	}
      else if (strcmp (size, "larger") == 0)
	{
	  if (tag)
	    {
	      tag->scale_level_delta += 1;
	      tag->scale_level += 1;
	    }
	}
      else if (parse_absolute_size (tag, size))
	; /* nothing */
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("Value of 'size' attribute on <span> tag on line %d "
			 "could not be parsed; should be an integer, or a "
			 "string such as 'small', not '%s'"),
		       line_number, size);
	  goto error;
	}
    }

  if (G_UNLIKELY (style))
    {
      PangoStyle pango_style;

      if (pango_parse_style (style, &pango_style, FALSE))
	add_attribute (tag, pango_attr_style_new (pango_style));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'style' attribute "
			 "on <span> tag, line %d; valid values are "
			 "'normal', 'oblique', 'italic'"),
		       style, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (weight))
    {
      PangoWeight pango_weight;

      if (pango_parse_weight (weight, &pango_weight, FALSE))
	add_attribute (tag,
		       pango_attr_weight_new (pango_weight));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'weight' "
			 "attribute on <span> tag, line %d; valid "
			 "values are for example 'light', 'ultrabold' or a number"),
		       weight, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (variant))
    {
      PangoVariant pango_variant;

      if (pango_parse_variant (variant, &pango_variant, FALSE))
	add_attribute (tag, pango_attr_variant_new (pango_variant));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'variant' "
			 "attribute on <span> tag, line %d; valid values are "
			 "'normal', 'smallcaps'"),
		       variant, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (stretch))
    {
      PangoStretch pango_stretch;

      if (pango_parse_stretch (stretch, &pango_stretch, FALSE))
	add_attribute (tag, pango_attr_stretch_new (pango_stretch));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'stretch' "
			 "attribute on <span> tag, line %d; valid "
			 "values are for example 'condensed', "
			 "'ultraexpanded', 'normal'"),
		       stretch, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (foreground))
    {
      PangoColor color;

      if (!span_parse_color ("foreground", foreground, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_foreground_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (background))
    {
      PangoColor color;

      if (!span_parse_color ("background", background, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_background_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (underline))
    {
      PangoUnderline ul = PANGO_UNDERLINE_NONE;

      if (!span_parse_enum ("underline", underline, PANGO_TYPE_UNDERLINE, &ul, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_underline_new (ul));
    }

  if (G_UNLIKELY (underline_color))
    {
      PangoColor color;

      if (!span_parse_color ("underline_color", underline_color, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_underline_color_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (gravity))
    {
      PangoGravity gr = PANGO_GRAVITY_SOUTH;

      if (!span_parse_enum ("gravity", gravity, PANGO_TYPE_GRAVITY, &gr, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_gravity_new (gr));
    }

  if (G_UNLIKELY (gravity_hint))
    {
      PangoGravityHint hint = PANGO_GRAVITY_HINT_NATURAL;

      if (!span_parse_enum ("gravity_hint", gravity_hint, PANGO_TYPE_GRAVITY_HINT, &hint, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_gravity_hint_new (hint));
    }

  if (G_UNLIKELY (strikethrough))
    {
      gboolean b = FALSE;

      if (!span_parse_boolean ("strikethrough", strikethrough, &b, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_strikethrough_new (b));
    }

  if (G_UNLIKELY (strikethrough_color))
    {
      PangoColor color;

      if (!span_parse_color ("strikethrough_color", strikethrough_color, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_strikethrough_color_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (fallback))
    {
      gboolean b = FALSE;

      if (!span_parse_boolean ("fallback", fallback, &b, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_fallback_new (b));
    }

  if (G_UNLIKELY (rise))
    {
      gint n = 0;

      if (!span_parse_int ("rise", rise, &n, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_rise_new (n));
    }

  if (G_UNLIKELY (letter_spacing))
    {
      gint n = 0;

      if (!span_parse_int ("letter_spacing", letter_spacing, &n, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_letter_spacing_new (n));
    }

  if (G_UNLIKELY (lang))
    {
      add_attribute (tag,
		     pango_attr_language_new (pango_language_from_string (lang)));
    }

  return TRUE;

 error:

  return FALSE;
}
Ejemplo n.º 15
0
/**
 * gimp_label_set_attributes:
 * @label: a #GtkLabel
 * @...:   a list of PangoAttrType and value pairs terminated by -1.
 *
 * Sets Pango attributes on a #GtkLabel in a more convenient way than
 * gtk_label_set_attributes().
 *
 * This function is useful if you want to change the font attributes
 * of a #GtkLabel. This is an alternative to using PangoMarkup which
 * is slow to parse and akward to handle in an i18n-friendly way.
 *
 * The attributes are set on the complete label, from start to end. If
 * you need to set attributes on part of the label, you will have to
 * use the PangoAttributes API directly.
 *
 * Since: 2.2
 **/
void
gimp_label_set_attributes (GtkLabel *label,
                           ...)
{
    PangoAttribute *attr  = NULL;
    PangoAttrList  *attrs;
    va_list         args;

    g_return_if_fail (GTK_IS_LABEL (label));

    attrs = pango_attr_list_new ();

    va_start (args, label);

    do
    {
        PangoAttrType attr_type = va_arg (args, PangoAttrType);

        if (attr_type == -1)
            attr_type = PANGO_ATTR_INVALID;

        switch (attr_type)
        {
        case PANGO_ATTR_LANGUAGE:
            attr = pango_attr_language_new (va_arg (args, PangoLanguage *));
            break;

        case PANGO_ATTR_FAMILY:
            attr = pango_attr_family_new (va_arg (args, const gchar *));
            break;

        case PANGO_ATTR_STYLE:
            attr = pango_attr_style_new (va_arg (args, PangoStyle));
            break;

        case PANGO_ATTR_WEIGHT:
            attr = pango_attr_weight_new (va_arg (args, PangoWeight));
            break;

        case PANGO_ATTR_VARIANT:
            attr = pango_attr_variant_new (va_arg (args, PangoVariant));
            break;

        case PANGO_ATTR_STRETCH:
            attr = pango_attr_stretch_new (va_arg (args, PangoStretch));
            break;

        case PANGO_ATTR_SIZE:
            attr = pango_attr_size_new (va_arg (args, gint));
            break;

        case PANGO_ATTR_FONT_DESC:
            attr = pango_attr_font_desc_new (va_arg (args,
                                             const PangoFontDescription *));
            break;

        case PANGO_ATTR_FOREGROUND:
        {
            const PangoColor *color = va_arg (args, const PangoColor *);

            attr = pango_attr_foreground_new (color->red,
                                              color->green,
                                              color->blue);
        }
        break;

        case PANGO_ATTR_BACKGROUND:
        {
            const PangoColor *color = va_arg (args, const PangoColor *);

            attr = pango_attr_background_new (color->red,
                                              color->green,
                                              color->blue);
        }
        break;

        case PANGO_ATTR_UNDERLINE:
            attr = pango_attr_underline_new (va_arg (args, PangoUnderline));
            break;

        case PANGO_ATTR_STRIKETHROUGH:
            attr = pango_attr_strikethrough_new (va_arg (args, gboolean));
            break;

        case PANGO_ATTR_RISE:
            attr = pango_attr_rise_new (va_arg (args, gint));
            break;

        case PANGO_ATTR_SCALE:
            attr = pango_attr_scale_new (va_arg (args, gdouble));
            break;

        default:
            g_warning ("%s: invalid PangoAttribute type %d",
                       G_STRFUNC, attr_type);
        case PANGO_ATTR_INVALID:
            attr = NULL;
            break;
        }

        if (attr)
        {
            attr->start_index = 0;
            attr->end_index   = -1;
            pango_attr_list_insert (attrs, attr);
        }
    }
    while (attr);

    va_end (args);

    gtk_label_set_attributes (label, attrs);
    pango_attr_list_unref (attrs);
}
Ejemplo n.º 16
0
/* This function is used by gtk_text_cell_accessible_get_offset_at_point()
 * and gtk_text_cell_accessible_get_character_extents(). There is no
 * cached PangoLayout so we must create a temporary one using this function.
 */
static PangoLayout *
create_pango_layout (GtkTextCellAccessible *text)
{
  GdkRGBA *foreground_rgba;
  PangoAttrList *attr_list, *attributes;
  PangoLayout *layout;
  PangoUnderline uline, underline;
  PangoFontMask mask;
  PangoFontDescription *font_desc;
  gboolean foreground_set, strikethrough_set, strikethrough;
  gboolean scale_set, underline_set, rise_set;
  gchar *renderer_text;
  gdouble scale;
  gint rise;
  GtkRendererCellAccessible *gail_renderer;
  GtkCellRendererText *gtk_renderer;

  gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);

  g_object_get (gtk_renderer,
                "text", &renderer_text,
                "attributes", &attributes,
                "foreground-set", &foreground_set,
                "foreground-rgba", &foreground_rgba,
                "strikethrough-set", &strikethrough_set,
                "strikethrough", &strikethrough,
                "font-desc", &font_desc,
                "scale-set", &scale_set,
                "scale", &scale,
                "underline-set", &underline_set,
                "underline", &underline,
                "rise-set", &rise_set,
                "rise", &rise,
                NULL);

  layout = gtk_widget_create_pango_layout (get_widget (text), renderer_text);

  if (attributes)
    attr_list = pango_attr_list_copy (attributes);
  else
    attr_list = pango_attr_list_new ();

  if (foreground_set)
    {
      add_attr (attr_list, pango_attr_foreground_new (foreground_rgba->red * 65535,
                                                      foreground_rgba->green * 65535,
                                                      foreground_rgba->blue * 65535));
    }

  if (strikethrough_set)
    add_attr (attr_list,
              pango_attr_strikethrough_new (strikethrough));

  mask = pango_font_description_get_set_fields (font_desc);

  if (mask & PANGO_FONT_MASK_FAMILY)
    add_attr (attr_list,
      pango_attr_family_new (pango_font_description_get_family (font_desc)));

  if (mask & PANGO_FONT_MASK_STYLE)
    add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (font_desc)));

  if (mask & PANGO_FONT_MASK_VARIANT)
    add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (font_desc)));

  if (mask & PANGO_FONT_MASK_WEIGHT)
    add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (font_desc)));

  if (mask & PANGO_FONT_MASK_STRETCH)
    add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (font_desc)));

  if (mask & PANGO_FONT_MASK_SIZE)
    add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (font_desc)));

  if (scale_set && scale != 1.0)
    add_attr (attr_list, pango_attr_scale_new (scale));

  if (underline_set)
    uline = underline;
  else
    uline = PANGO_UNDERLINE_NONE;

  if (uline != PANGO_UNDERLINE_NONE)
    add_attr (attr_list,
              pango_attr_underline_new (underline));

  if (rise_set)
    add_attr (attr_list, pango_attr_rise_new (rise));

  pango_layout_set_attributes (layout, attr_list);
  pango_layout_set_width (layout, -1);
  pango_attr_list_unref (attr_list);

  pango_font_description_free (font_desc);
  pango_attr_list_unref (attributes);
  g_free (renderer_text);
  gdk_rgba_free (foreground_rgba);

  return layout;
}
Ejemplo n.º 17
0
static IgtkFont* gtkFindFont(const char *standardfont)
{
  PangoFontMetrics* metrics;
  PangoFontDescription* fontdesc;
  int i, 
      is_underline = 0,
      is_strikeout = 0,
      count = iupArrayCount(gtk_fonts);

  IgtkFont* fonts = (IgtkFont*)iupArrayGetData(gtk_fonts);

  /* Check if the standardfont already exists in cache */
  for (i = 0; i < count; i++)
  {
    if (iupStrEqualNoCase(standardfont, fonts[i].standardfont))
      return &fonts[i];
  }

  /* not found, create a new one */
  {
    int size = 0, is_pango = 0;
    int is_bold = 0,
      is_italic = 0;
    char typeface[1024];
    const char* mapped_name;

    /* parse the old Windows format first */
    if (!iupFontParseWin(standardfont, typeface, &size, &is_bold, &is_italic, &is_underline, &is_strikeout))
    {
      if (!iupFontParseX(standardfont, typeface, &size, &is_bold, &is_italic, &is_underline, &is_strikeout))
      {
        if (!iupFontParsePango(standardfont, typeface, &size, &is_bold, &is_italic, &is_underline, &is_strikeout))
          return NULL;
        else
          is_pango = 1;
      }
    }

    mapped_name = iupFontGetPangoName(typeface);
    if (mapped_name)
      strcpy(typeface, mapped_name);

    if (is_pango && !is_underline && !is_strikeout && size>0)
      fontdesc = pango_font_description_from_string(standardfont);
    else
    {
      char new_standardfont[200];
      if (size<0)
      {
        double res = ((double)gdk_screen_get_width(gdk_screen_get_default()) / (double)gdk_screen_get_width_mm(gdk_screen_get_default())); /* pixels/mm */
        /* 1 point = 1/72 inch     1 inch = 25.4 mm */
        /* pixel = ((point/72)*25.4)*pixel/mm */
        size = (int)((-size/res)*2.83464567 + 0.5); /* from pixels to points */
      }

      sprintf(new_standardfont, "%s, %s%s%d", typeface, is_bold?"Bold ":"", is_italic?"Italic ":"", size);

      fontdesc = pango_font_description_from_string(new_standardfont);
    }
  }

  if (!fontdesc) 
    return NULL;

  /* create room in the array */
  fonts = (IgtkFont*)iupArrayInc(gtk_fonts);

  strcpy(fonts[i].standardfont, standardfont);
  fonts[i].fontdesc = fontdesc;
  fonts[i].strikethrough = pango_attr_strikethrough_new(is_strikeout? TRUE: FALSE);
  fonts[i].underline = pango_attr_underline_new(is_underline? PANGO_UNDERLINE_SINGLE: PANGO_UNDERLINE_NONE);
  fonts[i].layout = pango_layout_new(gtk_fonts_context);

  metrics = pango_context_get_metrics(gtk_fonts_context, fontdesc, pango_context_get_language(gtk_fonts_context));
  fonts[i].charheight = pango_font_metrics_get_ascent(metrics) + pango_font_metrics_get_descent(metrics);
  fonts[i].charheight = IUPGTK_PANGOUNITS2PIXELS(fonts[i].charheight);
  fonts[i].charwidth = pango_font_metrics_get_approximate_char_width(metrics);
  fonts[i].charwidth = IUPGTK_PANGOUNITS2PIXELS(fonts[i].charwidth);
  pango_font_metrics_unref(metrics); 

  gtkFontUpdate(&(fonts[i]));

  return &fonts[i];
}