Example #1
0
PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
		const char *text, double scale, bool markup) {
	PangoLayout *layout = pango_cairo_create_layout(cairo);
	PangoAttrList *attrs;
	if (markup) {
		char *buf;
		GError *error = NULL;
		if (pango_parse_markup(text, -1, 0, &attrs, &buf, NULL, &error)) {
			pango_layout_set_text(layout, buf, -1);
			free(buf);
		} else {
			sway_log(SWAY_ERROR, "pango_parse_markup '%s' -> error %s", text,
					error->message);
			g_error_free(error);
			markup = false; // fallback to plain text
		}
	}
	if (!markup) {
		attrs = pango_attr_list_new();
		pango_layout_set_text(layout, text, -1);
	}

	pango_attr_list_insert(attrs, pango_attr_scale_new(scale));
	PangoFontDescription *desc = pango_font_description_from_string(font);
	pango_layout_set_font_description(layout, desc);
	pango_layout_set_single_paragraph_mode(layout, 1);
	pango_layout_set_attributes(layout, attrs);
	pango_attr_list_unref(attrs);
	pango_font_description_free(desc);
	return layout;
}
Example #2
0
char *fe_menu_add(menu_entry *me) {
	char *text;

	menu_foreach_gui(me, menu_add_cb);

	if (!me->markup)
		return NULL;

	if (!pango_parse_markup(me->label, -1, 0, NULL, &text, NULL, NULL))
		return NULL;

	/* return the label with markup stripped */
	return text;
}
Example #3
0
static	void
SetLabel(
	GtkWidget		*widget,
	WidgetData	*wdata,
	_Label			*data)
{
ENTER_FUNC;
	SetCommon(widget,wdata);
	if (data->text != NULL) {
		if (pango_parse_markup(data->text,-1,0,NULL,NULL,NULL,NULL)) {
			gtk_label_set_markup(GTK_LABEL(widget),data->text);
		} else {
			gtk_label_set_text(GTK_LABEL(widget),data->text);
		}
	}
LEAVE_FUNC;
}
Example #4
0
bool ttext::set_text(const std::string& text, const bool markedup)
{
	if(markedup != markedup_text_ || text != text_) {
		assert(layout_);

		const wide_string wide = utils::string_to_wstring(text);
		const std::string narrow = utils::wstring_to_string(wide);
		if(text != narrow) {
			ERR_GUI_L << "ttext::" << __func__
					<< " text '" << text
					<< "' contains invalid utf-8, trimmed the invalid parts.\n";
		}
		if(markedup) {
			if(!pango_parse_markup(narrow.c_str(), narrow.size()
						, 0, NULL, NULL, NULL, NULL)) {

				ERR_GUI_L << "ttext::" << __func__
						<< " text '" << narrow
						<< "' has broken markup, set to normal text.\n";

				set_text(_("The text contains invalid markup: ") + narrow, false);
				return false;
			}
			pango_layout_set_markup(layout_, narrow.c_str(), narrow.size());
		} else {
			/*
			 * pango_layout_set_text after pango_layout_set_markup might
			 * leave the layout in an undefined state regarding markup so
			 * clear it unconditionally.
			 */
			pango_layout_set_attributes(layout_, NULL);
			pango_layout_set_text(layout_, narrow.c_str(), narrow.size());
		}
		text_ = narrow;
		length_ = wide.size();
		markedup_text_ = markedup;
		calculation_dirty_ = true;
		surface_dirty_ = true;
	}

	return true;
}
Example #5
0
PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, const char *text,
		int32_t scale, bool markup) {
	PangoLayout *layout = pango_cairo_create_layout(cairo);
	PangoAttrList *attrs;
	if (markup) {
		char *buf;
		pango_parse_markup(text, -1, 0, &attrs, &buf, NULL, NULL);
		pango_layout_set_markup(layout, buf, -1);
		free(buf);
	} else {
		attrs = pango_attr_list_new();
		pango_layout_set_text(layout, text, -1);
	}
	pango_attr_list_insert(attrs, pango_attr_scale_new(scale));
	PangoFontDescription *desc = pango_font_description_from_string(font);
	pango_layout_set_font_description(layout, desc);
	pango_layout_set_single_paragraph_mode(layout, 1);
	pango_layout_set_attributes(layout, attrs);
	pango_attr_list_unref(attrs);
	pango_font_description_free(desc);
	return layout;
}
Example #6
0
/* This method is from rbpangoattribute.c */
static VALUE
rg_s_parse_markup(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
{
    VALUE markup_text, accel_marker;
    PangoAttrList *pattr_list;
    gchar* gtext;
    gunichar accel_char;
    GError *error = NULL;
    gboolean ret;
    char c;
    VALUE text = Qnil;
    VALUE attr_list = Qnil;

    rb_scan_args(argc, argv, "11", &markup_text, &accel_marker);

    if (NIL_P(markup_text)) rb_raise(rb_eRuntimeError, "1st argument can't accept nil");

    StringValue(markup_text);
    ret = pango_parse_markup(RSTRING_PTR(markup_text),
                             RSTRING_LEN(markup_text),
                             NIL_P(accel_marker) ? 0 : NUM2CHR(accel_marker),
                             &pattr_list, &gtext, &accel_char, &error);

    if (!ret) RAISE_GERROR(error);

    if (pattr_list){
        attr_list = PANGOATTRLIST2RVAL(pattr_list); 
        pango_attr_list_unref(pattr_list);
    }

    c = (char)accel_char;
    if (text){
        text = CSTR2RVAL(gtext);
        g_free(gtext);
    }
    return rb_ary_new3(3, attr_list, text,
                       accel_char ? rb_str_new(&c, 1) : Qnil);
}
Example #7
0
static boolean pango_textlayout(textpara_t * para, char **fontpath)
{
    static char buf[1024];  /* returned in fontpath, only good until next call */
    static PangoFontMap *fontmap;
    static PangoContext *context;
    static PangoFontDescription *desc;
    static char *fontname;
    static double fontsize;
    static gv_font_map* gv_fmap;
    char *fnt, *psfnt = NULL;
    PangoLayout *layout;
    PangoRectangle logical_rect;
    cairo_font_options_t* options;
    PangoFont *font;
#ifdef ENABLE_PANGO_MARKUP
    PangoAttrList *attrs;
    GError *error = NULL;
    int flags;
#endif
    char *text;
    double textlayout_scale;

    if (!context) {
	fontmap = pango_cairo_font_map_new();
	gv_fmap = get_font_mapping(fontmap);
	context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
	options=cairo_font_options_create();
	cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
	cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
	pango_cairo_context_set_font_options(context, options);
	pango_cairo_context_set_resolution(context, FONT_DPI);
	cairo_font_options_destroy(options);
	g_object_unref(fontmap);
    }

    if (!fontname || strcmp(fontname, para->fontname) != 0 || fontsize != para->fontsize) {
	fontname = para->fontname;
	fontsize = para->fontsize;
	pango_font_description_free (desc);

	if (para->postscript_alias) {
	    psfnt = fnt = gv_fmap[para->postscript_alias->xfig_code].gv_font;
	    if(!psfnt)
		psfnt = fnt = pango_psfontResolve (para->postscript_alias);
	}
	else
	    fnt = fontname;

	desc = pango_font_description_from_string(fnt);
        /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */
        pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE));

        if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) {  /* -v support */
	    const char *fontclass;

	    fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font));

	    buf[0] = '\0';
	    if (psfnt) {
		strcat(buf, "(ps:pango  ");
		strcat(buf, psfnt);
		strcat(buf, ") ");
	    }
	    strcat(buf, "(");
	    strcat(buf, fontclass);
	    strcat(buf, ") ");
#ifdef HAVE_PANGO_FC_FONT_LOCK_FACE
	    if (strcmp(fontclass, "PangoCairoFcFont") == 0) {
	        FT_Face face;
	        PangoFcFont *fcfont;
	        FT_Stream stream;
	        FT_StreamDesc streamdesc;
	        fcfont = PANGO_FC_FONT(font);
	        face = pango_fc_font_lock_face(fcfont);
	        if (face) {
		    strcat(buf, "\"");
		    strcat(buf, face->family_name);
		    strcat(buf, ", ");
		    strcat(buf, face->style_name);
		    strcat(buf, "\" ");
    
		    stream = face->stream;
		    if (stream) {
			streamdesc = stream->pathname;
			if (streamdesc.pointer)
			    strcat(buf, (char*)streamdesc.pointer);
		        else
			    strcat(buf, "*no pathname available*");
		    }
		    else
			strcat(buf, "*no stream available*");
		}
	        pango_fc_font_unlock_face(fcfont);
	    }
	    else
#endif
	    {
    		PangoFontDescription *tdesc;
		char *tfont;
		
	        tdesc = pango_font_describe(font);
	        tfont = pango_font_description_to_string(tdesc);
	        strcat(buf, "\"");
	        strcat(buf, tfont);
	        strcat(buf, "\" ");
	        g_free(tfont);
	    }
            *fontpath = buf;
        }
    }

#ifdef ENABLE_PANGO_MARKUP
    if ((para->font) && (flags = para->font->flags)) {
	char* markup = N_NEW(strlen(para->str) + sizeof(FULL_MARKUP), char);
	strcpy(markup,"<span");

	if (flags & HTML_BF)
	    strcat(markup," weight=\"bold\"");
	if (flags & HTML_IF)
	    strcat(markup," style=\"italic\"");
	if (flags & HTML_UL)
	    strcat(markup," underline=\"single\"");
	strcat (markup,">");

	if (flags & HTML_SUP)
	    strcat(markup,"<sup>");
	if (flags & HTML_SUB)
	    strcat(markup,"<sub>");

	strcat (markup,para->str);

	if (flags & HTML_SUB)
	    strcat(markup,"</sub>");
	if (flags & HTML_SUP)
	    strcat(markup,"</sup>");

	strcat (markup,"</span>");
	if (!pango_parse_markup (markup, -1, 0, &attrs, &text, NULL, &error)) {
	    fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message);
	    text = para->str;
	    attrs = NULL;
	}
	free (markup);
    }
Example #8
0
/*
 * Sets the properties of the widget. This is used for both applying the
 * properties changed in the property editor, and also for loading.
 */
void
gb_label_set_standard_properties (GtkWidget * widget,
				  GbWidgetSetArgData * data,
				  const char *label_p,
				  const char *use_underline_p,
				  const char *use_markup_p,
				  const char *justify_p,
				  const char *wrap_p,
				  const char *selectable_p,
				  const char *xalign_p,
				  const char *yalign_p,
				  const char *xpad_p,
				  const char *ypad_p,
				  const char *focus_target_p)
{
  gchar *label, *justify, *accel_target;
  const gchar *label_text;
  gfloat xalign, yalign;
  gint xpad, ypad, i;
  gboolean wrap, selectable, set_alignment = FALSE, set_padding = FALSE;
  gboolean use_underline, use_markup;
  gboolean set_label = FALSE;

  use_underline = gb_widget_input_bool (data, use_underline_p);
  if (data->apply)
    gtk_label_set_use_underline (GTK_LABEL (widget), use_underline);

  use_markup = gb_widget_input_bool (data, use_markup_p);
  if (data->apply)
    {
      set_label = TRUE;
      gtk_object_set_data (GTK_OBJECT (widget), use_markup_p,
			   GINT_TO_POINTER (use_markup));
    }

  label = gb_widget_input_text (data, label_p);
  if (data->apply)
    {
      set_label = TRUE;
      label_text = label;
    }
  else
    {
      label_text = gtk_label_get_label (GTK_LABEL (widget));
    }

  if (set_label)
    {
      gboolean prev_use_markup;

      use_markup = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget),
							 use_markup_p));

      /* We try to parse the markup here, and if it isn't valid, we will
	 turn use_markup off and show it as plain text. */
      if (use_markup)
	{
	  GError *error = NULL;
	  gunichar accel_marker = 0;
	  PangoAttrList *attrs = NULL;
	  gunichar accel_char = 0;
	  gchar *text = NULL;

	  if (gtk_label_get_use_underline (GTK_LABEL (widget)))
	    accel_marker = '_';

	  /* We check it is valid markup. If it isn't we will set "use_markup"
	     to FALSE. Note that we don't need attrs, text, or accel_char but
	     it seems to crash otherwise. */
	  if (!pango_parse_markup (label_text, -1, accel_marker, &attrs, &text,
				   &accel_char, &error))
	    {
	      use_markup = FALSE;
	      g_error_free (error);
	    }
	  else
	    {
	      if (attrs)
		pango_attr_list_unref (attrs);
	      g_free (text);
	    }
	}

      /* If we are turning use_markup off, we want to do that before setting
	 the text. If we are turning it on, we want to do it after. */
      prev_use_markup = gtk_label_get_use_markup (GTK_LABEL (widget));
      if (!use_markup && prev_use_markup)
	gtk_label_set_use_markup (GTK_LABEL (widget), use_markup);

      gtk_label_set_label (GTK_LABEL (widget), label_text);

      if (use_markup && !prev_use_markup)
	gtk_label_set_use_markup (GTK_LABEL (widget), use_markup);
    }

  if (data->action == GB_APPLYING)
    g_free (label);

  justify = gb_widget_input_choice (data, justify_p);
  if (data->apply)
    {
      for (i = 0; i < sizeof (GbJustifyValues) / sizeof (GbJustifyValues[0]);
	   i++)
	{
	  if (!strcmp (justify, GbJustifyChoices[i])
	      || !strcmp (justify, GbJustifySymbols[i]))
	    {
	      gtk_label_set_justify (GTK_LABEL (widget), GbJustifyValues[i]);
	      break;
	    }
	}
    }

  wrap = gb_widget_input_bool (data, wrap_p);
  if (data->apply)
    gtk_label_set_line_wrap (GTK_LABEL (widget), wrap);

  selectable = gb_widget_input_bool (data, selectable_p);
  if (data->apply)
    gtk_label_set_selectable (GTK_LABEL (widget), selectable);

  xalign = gb_widget_input_float (data, xalign_p);
  if (data->apply)
    set_alignment = TRUE;
  else
    xalign = GTK_MISC (widget)->xalign;

  yalign = gb_widget_input_float (data, yalign_p);
  if (data->apply)
    set_alignment = TRUE;
  else
    yalign = GTK_MISC (widget)->yalign;

  if (set_alignment)
    gtk_misc_set_alignment (GTK_MISC (widget), xalign, yalign);

  xpad = gb_widget_input_int (data, xpad_p);
  if (data->apply)
    set_padding = TRUE;
  else
    xpad = GTK_MISC (widget)->xpad;

  ypad = gb_widget_input_int (data, ypad_p);
  if (data->apply)
    set_padding = TRUE;
  else
    ypad = GTK_MISC (widget)->ypad;

  if (set_padding)
    gtk_misc_set_padding (GTK_MISC (widget), xpad, ypad);

  /* Labels not in buttons may have a focus target widget. */
  accel_target = gb_widget_input_combo (data, focus_target_p);
  if (data->apply)
    {
      if (!gb_label_find_mnemonic_widget (widget))
	{
	  if (!strcmp (accel_target, _("Auto")))
	    accel_target = NULL;

	  gtk_object_set_data_full (GTK_OBJECT (widget), focus_target_p,
				    g_strdup (accel_target),
				    accel_target ? g_free : NULL);
	}
    }
}
Example #9
0
void
fallback_dialog_show (Defaults*    d,
		      const gchar* sender,
		      const gchar* app_name,
		      int          id,
		      const gchar* title_text,
		      const gchar* _body_message,
		      gchar**      actions)
{
	GtkWidget* dialog;
	GtkWidget* hbox;
	GtkWidget* vbox;
	GtkWidget* title;
	GtkWidget* body;
	GtkWidget* image;
	gchar*     body_message = NULL;
	gchar*     new_body_message = NULL;
	guint      gap = EM2PIXELS (defaults_get_margin_size (d), d);
	gboolean   success = FALSE;
	GError*    error = NULL;

	if (!IS_DEFAULTS (d) ||
	    !sender          ||
	    !app_name        ||
	    !title_text      ||
	    !_body_message   ||
	    !actions)
		return;

	DialogInfo* dialog_info = g_new0 (DialogInfo, 1);
	if (!dialog_info)
		return;

	dialog_info->id = id;
	dialog_info->sender = g_strdup(sender);

	dialog = gtk_dialog_new ();

	hbox = g_object_new (GTK_TYPE_HBOX,
			     "spacing", gap,
			     "border-width", 12,
			     NULL);

	// We deliberately use the gtk-dialog-warning icon rather than
	// the specified one to discourage people from trying to use
	// the notification system as a way of showing custom alert
	// dialogs.
	image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
					  GTK_ICON_SIZE_DIALOG);
	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
	gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);

	vbox = g_object_new (GTK_TYPE_VBOX,
			     NULL);

	title = gtk_label_new (NULL);
	gtk_label_set_text (GTK_LABEL (title), title_text);

	gtk_label_set_line_wrap (GTK_LABEL (title), TRUE);

	body = gtk_label_new (NULL);
	body_message = filter_text (_body_message);
	if (body_message)
	{
		success = pango_parse_markup (body_message,
					      -1,
					      0,
					      NULL,
					      &new_body_message,
					      NULL,
					      &error);

		if (error && !success)
		{
			g_warning ("fallback_dialog_show(): Got error \"%s\"\n",
		        	   error->message);
			g_error_free (error);
			error = NULL;
		}
	}

	if (new_body_message)
	{
		gtk_label_set_text (GTK_LABEL (body), new_body_message);
		g_free (new_body_message);
	}
	else
		gtk_label_set_text (GTK_LABEL (body), body_message);

	g_free (body_message);

	gtk_label_set_line_wrap (GTK_LABEL (body), TRUE);

	gtk_misc_set_alignment (GTK_MISC (title), 0.0, 0.0);
	gtk_box_pack_start (GTK_BOX (vbox), title, TRUE, TRUE, 0);

	gtk_misc_set_alignment (GTK_MISC (body), 0.0, 0.0);
	gtk_box_pack_start (GTK_BOX (vbox), body, TRUE, TRUE, 0);

	gtk_container_add (GTK_CONTAINER (hbox), vbox);

	gtk_container_add (GTK_CONTAINER (
				   gtk_dialog_get_content_area (
					   GTK_DIALOG (dialog))),
			   hbox);

	gtk_container_set_border_width (GTK_CONTAINER (dialog), 2);

	gtk_window_set_position (GTK_WINDOW (dialog),
				 GTK_WIN_POS_CENTER);
	gtk_window_set_default_size (GTK_WINDOW (dialog),
				     EM2PIXELS (defaults_get_bubble_width (d) * 1.2f, d),
				     -1);
	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
	gtk_window_set_title (GTK_WINDOW (dialog), app_name);
	gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE);

	// is it a bad notification with actions?
	if (actions[0] != NULL)
		add_pathological_action_buttons (dialog, actions);

	GtkButton *cancel = GTK_BUTTON (
		gtk_dialog_add_button (GTK_DIALOG (dialog),
				       GTK_STOCK_CANCEL,
				       GTK_RESPONSE_CANCEL));
	g_signal_connect_swapped (G_OBJECT (cancel),
				  "button-release-event",
				  G_CALLBACK (handle_close),
				  dialog);
	gtk_widget_set_can_default(GTK_WIDGET(cancel), FALSE);

	g_signal_connect (G_OBJECT (dialog),
			  "response",
			  G_CALLBACK (handle_close),
			  dialog);
		
		
	GtkButton *ok = GTK_BUTTON (
		gtk_dialog_add_button (GTK_DIALOG (dialog),
				       GTK_STOCK_OK,
				       GTK_RESPONSE_OK));
	g_object_set_data_full (G_OBJECT (ok),
				"_libnotify_action",
				g_strdup ("default"),
				g_free);
	g_signal_connect (G_OBJECT (ok),
			  "button-release-event",
			  G_CALLBACK (handle_response),
			  dialog);
	gtk_widget_set_can_default(GTK_WIDGET(ok), FALSE);

	g_object_set_data (G_OBJECT (dialog),
			   "_dialog_info",
			   dialog_info);

	g_signal_connect (G_OBJECT (dialog),
			  "button-release-event",
			  G_CALLBACK (handle_response),
			  dialog);

	gtk_window_set_focus (GTK_WINDOW (dialog),
			      NULL);
	gtk_window_set_default (GTK_WINDOW (dialog),
				NULL);

	gtk_widget_show_all (dialog);
}
Example #10
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d P A N G O I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadPANGOImage() reads an image in the Pango Markup Language Format.
%
%  The format of the ReadPANGOImage method is:
%
%      Image *ReadPANGOImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadPANGOImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  cairo_font_options_t
    *font_options;

  cairo_surface_t
    *surface;

  char
    *caption,
    *property;

  cairo_t
    *cairo_image;

  const char
    *option;

  DrawInfo
    *draw_info;

  Image
    *image;

  MagickBooleanType
    status;

  PangoAlignment
    align;

  PangoContext
    *context;

  PangoFontMap
    *fontmap;

  PangoGravity
    gravity;

  PangoLayout
    *layout;

  PangoRectangle
    extent;

  PixelInfo
    fill_color;

  RectangleInfo
    page;

  register unsigned char
    *p;

  size_t
    stride;

  ssize_t
    y;

  unsigned char
    *pixels;

  /*
    Initialize Image structure.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info,exception);
  (void) ResetImagePage(image,"0x0+0+0");
  /*
    Format caption.
  */
  option=GetImageArtifact(image,"filename");
  if (option == (const char *) NULL)
    property=InterpretImageProperties(image_info,image,image_info->filename,
      exception);
  else
    if (LocaleNCompare(option,"pango:",6) == 0)
      property=InterpretImageProperties(image_info,image,option+6,exception);
    else
      property=InterpretImageProperties(image_info,image,option,exception);
  (void) SetImageProperty(image,"caption",property,exception);
  property=DestroyString(property);
  caption=ConstantString(GetImageProperty(image,"caption",exception));
  /*
    Get context.
  */
  fontmap=pango_cairo_font_map_new();
  pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap),
    image->resolution.x == 0.0 ? 90.0 : image->resolution.x);
  font_options=cairo_font_options_create();
  option=GetImageArtifact(image,"pango:hinting");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"none") != 0)
        cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_NONE);
      if (LocaleCompare(option,"full") != 0)
        cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_FULL);
    }
  context=pango_font_map_create_context(fontmap);
  pango_cairo_context_set_font_options(context,font_options);
  cairo_font_options_destroy(font_options);
  option=GetImageArtifact(image,"pango:language");
  if (option != (const char *) NULL)
    pango_context_set_language(context,pango_language_from_string(option));
  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
  pango_context_set_base_dir(context,draw_info->direction ==
    RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
  switch (draw_info->gravity)
  {
    case NorthGravity:
    {
      gravity=PANGO_GRAVITY_NORTH;
      break;
    }
    case NorthWestGravity:
    case WestGravity:
    case SouthWestGravity:
    {
      gravity=PANGO_GRAVITY_WEST;
      break;
    }
    case NorthEastGravity:
    case EastGravity:
    case SouthEastGravity:
    {
      gravity=PANGO_GRAVITY_EAST;
      break;
    }
    case SouthGravity:
    {
      gravity=PANGO_GRAVITY_SOUTH;
      break;
    }
    default:
    {
      gravity=PANGO_GRAVITY_AUTO;
      break;
    }
  }
  pango_context_set_base_gravity(context,gravity);
  option=GetImageArtifact(image,"pango:gravity-hint");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"line") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE);
      if (LocaleCompare(option,"natural") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL);
      if (LocaleCompare(option,"strong") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG);
    }
  /*
    Configure layout.
  */
  layout=pango_layout_new(context);
  option=GetImageArtifact(image,"pango:auto-dir");
  if (option != (const char *) NULL)
    pango_layout_set_auto_dir(layout,1);
  option=GetImageArtifact(image,"pango:ellipsize");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"end") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END);
      if (LocaleCompare(option,"middle") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE);
      if (LocaleCompare(option,"none") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE);
      if (LocaleCompare(option,"start") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START);
    }
  option=GetImageArtifact(image,"pango:justify");
  if (IfMagickTrue(IsStringTrue(option)))
    pango_layout_set_justify(layout,1);
  option=GetImageArtifact(image,"pango:single-paragraph");
  if (IfMagickTrue(IsStringTrue(option)))
    pango_layout_set_single_paragraph_mode(layout,1);
  option=GetImageArtifact(image,"pango:wrap");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_CHAR);
      if (LocaleCompare(option,"word") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD);
      if (LocaleCompare(option,"word-char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR);
    }
  option=GetImageArtifact(image,"pango:indent");
  if (option != (const char *) NULL)
    pango_layout_set_indent(layout,(int) ((StringToLong(option)*
      (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)*PANGO_SCALE+36)/
      90.0+0.5));
  switch (draw_info->align)
  {
    case CenterAlign: align=PANGO_ALIGN_CENTER; break;
    case RightAlign: align=PANGO_ALIGN_RIGHT; break;
    case LeftAlign: align=PANGO_ALIGN_LEFT; break;
    default:
    {
      if (draw_info->gravity == CenterGravity)
        {
          align=PANGO_ALIGN_CENTER;
          break;
        }
      align=PANGO_ALIGN_LEFT;
      break;
    }
  }
  if ((align != PANGO_ALIGN_CENTER) &&
      (draw_info->direction == RightToLeftDirection))
    align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align);
  pango_layout_set_alignment(layout,align);
  if (draw_info->font != (char *) NULL)
    {
      PangoFontDescription
        *description;

      /*
        Set font.
      */
      description=pango_font_description_from_string(draw_info->font);
      pango_font_description_set_size(description,(int) (PANGO_SCALE*
        draw_info->pointsize+0.5));
      pango_layout_set_font_description(layout,description);
      pango_font_description_free(description);
    }
  option=GetImageArtifact(image,"pango:markup");
  if ((option != (const char *) NULL) && (IsStringTrue(option) == MagickFalse))
    pango_layout_set_text(layout,caption,-1);
  else
    {
      GError
        *error;

      error=(GError *) NULL;
      if (pango_parse_markup(caption,-1,0,NULL,NULL,NULL,&error) == 0)
        (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
          error->message,"`%s'",image_info->filename);
      pango_layout_set_markup(layout,caption,-1);
    }
  pango_layout_context_changed(layout);
  page.x=0;
  page.y=0;
  if (image_info->page != (char *) NULL)
    (void) ParseAbsoluteGeometry(image_info->page,&page);
  if (image->columns == 0)
    {
      pango_layout_get_extents(layout,NULL,&extent);
      image->columns=(extent.x+extent.width+PANGO_SCALE/2)/PANGO_SCALE+2*page.x;
    }
  else
    {
      image->columns-=2*page.x;
      pango_layout_set_width(layout,(int) ((PANGO_SCALE*image->columns*
        (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)+45.0)/90.0+
        0.5));
    }
  if (image->rows == 0)
    {
      pango_layout_get_extents(layout,NULL,&extent);
      image->rows=(extent.y+extent.height+PANGO_SCALE/2)/PANGO_SCALE+2*page.y;
    }
  else
    {
      image->rows-=2*page.y;
      pango_layout_set_height(layout,(int) ((PANGO_SCALE*image->rows*
        (image->resolution.y == 0.0 ? 90.0 : image->resolution.y)+45.0)/90.0+
        0.5));
    }
  /*
    Render markup.
  */
  stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
    image->columns);
  pixels=(unsigned char *) AcquireQuantumMemory(image->rows,stride*
    sizeof(*pixels));
  if (pixels == (unsigned char *) NULL)
    {
      draw_info=DestroyDrawInfo(draw_info);
      caption=DestroyString(caption);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  surface=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32,
    image->columns,image->rows,stride);
  cairo_image=cairo_create(surface);
  cairo_set_operator(cairo_image,CAIRO_OPERATOR_CLEAR);
  cairo_paint(cairo_image);
  cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER);
  cairo_translate(cairo_image,page.x,page.y);
  pango_cairo_show_layout(cairo_image,layout);
  cairo_destroy(cairo_image);
  cairo_surface_destroy(surface);
  g_object_unref(layout);
  g_object_unref(fontmap);
  /*
    Convert surface to image.
  */
  (void) SetImageBackgroundColor(image,exception);
  p=pixels;
  GetPixelInfo(image,&fill_color);
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    register Quantum
      *q;

    register ssize_t
      x;

    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (Quantum *) NULL)
      break;
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      double
        gamma;

      fill_color.blue=(double) ScaleCharToQuantum(*p++);
      fill_color.green=(double) ScaleCharToQuantum(*p++);
      fill_color.red=(double) ScaleCharToQuantum(*p++);
      fill_color.alpha=(double) ScaleCharToQuantum(*p++);
      /*
        Disassociate alpha.
      */
      gamma=1.0-QuantumScale*fill_color.alpha;
      gamma=PerceptibleReciprocal(gamma);
      fill_color.blue*=gamma;
      fill_color.green*=gamma;
      fill_color.red*=gamma;
      CompositePixelOver(image,&fill_color,fill_color.alpha,q,(double)
        GetPixelAlpha(image,q),q);
      q+=GetPixelChannels(image);
    }
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
    if (image->previous == (Image *) NULL)
      {
        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
        image->rows);
        if (status == MagickFalse)
          break;
      }
  }
  /*
    Relinquish resources.
  */
  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
  draw_info=DestroyDrawInfo(draw_info);
  caption=DestroyString(caption);
  return(GetFirstImageInList(image));
}
int
main(int argc, char **argv)
{
    GtkWidget *widget;
    gchar *glade_xml_file;

    gtk_init(&argc, &argv);
    set_font();
    get_asf_share_dir_with_argv0(argv[0]);
    set_tiff_warning_handler();

    asfPrintStatus("\nASF MapReady:\n");
    const char *share_dir = get_asf_share_dir();

    if (!share_dir)
      // this actually should never happen with the current implementation
      // of get_asf_share_dir() -- always sets the share dir to something
      // even if it is a bad guess... in which case the next check will fail
      asfPrintError("Could not find the ASF share directory!\n");

    glade_xml_file = (gchar *)find_in_share("mapready.glade");
    if (!glade_xml_file)
      asfPrintError("Could not find the mapready.glade file!\n"
                    "It should be in the share files directory, here:\n"
                    "  %s\n", share_dir);
    glade_xml = glade_xml_new(glade_xml_file, NULL, NULL);
    if (!glade_xml)
      asfPrintError("Could not load the mapready.glade file!\n"
                    "This file may be corrupt. mapready.glade was found in:\n"
                    "  %s\n", share_dir);
    g_free(glade_xml_file);

    asfPrintStatus("Using share files directory: %s\n\n", share_dir);

    /* thumbnails supported in GTK 2.4 or greater */
#ifdef G_THREADS_ENABLED
    use_thumbnails = gtk_major_version >= 2 && gtk_minor_version >= 4;
#else
    use_thumbnails = FALSE;
#endif

#ifdef win32
    // On windows, ensure that our installed sh.exe is the one that is found,
    // by severely restricting the path.
    char pathenv[1024];
    sprintf(pathenv, "PATH=%s", get_asf_bin_dir());
    putenv(pathenv);
#endif

    if (!use_thumbnails)
    {
        printf("GTK Version < 2.4 -- output thumbnails disabled.\n");
    }
    else
    {
        // We will want to load thumbnails in other threads.
        if ( !g_thread_supported () ) {
            g_thread_init (NULL);
        }
    }

    /* allow FOPEN, FREAD, FWRITE to fail without aborting */
    caplib_behavior_on_error = BEHAVIOR_ON_ERROR_CONTINUE;

    /* add version number to window title, request a default size */
    char gtitle [256];
    sprintf (gtitle, "ASF MapReady: Version %s",
             MAPREADY_VERSION_STRING);

    widget = get_widget_checked("asf_convert");
    gtk_window_set_title(GTK_WINDOW(widget), gtitle);
    // commenting this out - now supported within glade
    //gtk_window_resize(GTK_WINDOW(widget), 1000, 700);

    /* select defaults for dropdowns & buttons & labeling */
    widget = get_widget_checked("scaling_method_combobox");
    set_combo_box_item(widget, SCALING_METHOD_SIGMA);

    widget = get_widget_checked("import_checkbutton");
    gtk_widget_set_sensitive(widget, FALSE);

    widget = get_widget_checked("input_data_type_combobox");
    set_combo_box_item(widget, INPUT_TYPE_AMP);

    widget = get_widget_checked("resample_option_menu");
    set_combo_box_item(widget, RESAMPLE_BILINEAR);

    // Populate the colormap drop-downs on both the import tab and in the
    // browse dialog
    populate_polsarpro_classification_optionmenu();
    widget = get_widget_checked("browse_select_colormap_optionmenu");
    gtk_option_menu_set_history(GTK_OPTION_MENU(widget), 0);

    widget = get_widget_checked("output_format_combobox");
    set_combo_box_item(widget, OUTPUT_FORMAT_JPEG);

    widget = get_widget_checked("geocode_checkbutton");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
    geocode_options_changed();
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), FALSE);

    widget = get_widget_checked("about_dialog_copyright_label");
    gtk_label_set_text(GTK_LABEL(widget), ASF_COPYRIGHT_STRING);

    // Hide latitude selection stuff until we start supporting
    // swath products (level 0) again
    widget = get_widget_checked("latitude_checkbutton");
    gtk_widget_hide(widget);
    widget = get_widget_checked("latitude_low_label");
    gtk_widget_hide(widget);
    widget = get_widget_checked("latitude_hi_label");
    gtk_widget_hide(widget);
    widget = get_widget_checked("latitude_low_entry");
    gtk_widget_hide(widget);
    widget = get_widget_checked("latitude_hi_entry");
    gtk_widget_hide(widget);

    // For now, do not allow manual offsets
    show_widget("hbox_tc_matching", FALSE);

    // This option is deprecated -- we always apply the fix now
    // and don't give the user the option of turning it off.  Probably
    // we can just delete all code associated with it, but for now we
    // just turn it on, and hide it.
    set_checked("apply_metadata_fix_checkbutton", TRUE);
    widget = get_widget_checked("apply_metadata_fix_checkbutton");
    gtk_widget_hide(widget);

    // Muck with the fonts in the About dialog
    widget = get_widget_checked("about_dialog_mapready_label");
    gchar *str = gtitle;
    gchar *text;
    PangoAttrList *attrs;
    sprintf(gtitle,
                "\n<b>ASF MapReady</b>\n"
                "<i>Remote Sensing Toolkit</i>\n"
                "ver. %s",
                MAPREADY_VERSION_STRING);
    if (strlen(SVN_REV)>0)
        sprintf(gtitle, "%s (build %s)", gtitle, SVN_REV);
    else
        strcat(gtitle, " (custom build)");

    pango_parse_markup(str, -1, 0, &attrs, &text, NULL, NULL);
    gtk_label_set_attributes(GTK_LABEL(widget), attrs);
    gtk_label_set_text(GTK_LABEL(widget), text);
    PangoFontDescription *font_desc =
      pango_font_description_from_string("Sans 12");
    gtk_widget_modify_font(widget, font_desc);

    // Muck with the "Select Processing Steps" label
    widget = get_widget_checked("select_processing_steps_label");
    str = gtitle;
    sprintf(gtitle, "<b><i>  Select Processing Steps:</i></b>");
    pango_parse_markup(str, -1, 0, &attrs, &text, NULL, NULL);
    gtk_label_set_attributes(GTK_LABEL(widget), attrs);
    gtk_label_set_text(GTK_LABEL(widget), text);
    font_desc = pango_font_description_from_string("Sans 12");
    gtk_widget_modify_font(widget, font_desc);

    /* fire handlers for hiding/showing stuff */
    output_format_combobox_changed();
    input_data_type_changed();
    geocode_options_changed();
    load_external_commands();
    external_settings_changed();
    set_toolbar_images();
    show_execute_button(TRUE);

    /* build columns in the files section */
    show_full_paths = FALSE; // Set before setup_files_list(), default to FALSE
    widget = get_widget_checked("show_full_path_names_checkbutton");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), FALSE);
    setup_files_list();

    /* allow multiple selects */
    widget = get_widget_checked("input_file_selection");
    gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(widget), TRUE);

    /* drag-n-drop setup */
    setup_dnd();

    /* right-click menu setup */
    setup_popup_menu();

    /* bands dropdown setup*/
    setup_band_comboboxes();

    current_naming_scheme = naming_scheme_default();

    /* set initial vpanel setting */
    //widget = get_widget_checked("vertical_pane");
    //gtk_paned_set_position(GTK_PANED(widget), 240);

    /* Connect signal handlers.  */
    glade_xml_signal_autoconnect (glade_xml);

    /* initial flag settings */
    processing = FALSE;
    settings_on_execute = NULL;

    /* explicit call to the function that refreshes the "summary" */
    /* section when options are changed, so get the settings      */
    /* initially in there                                         */
    input_data_formats_changed();
    input_data_type_combobox_changed();
    default_to_terrcorr_on();
    default_to_keep_temp();
    terrcorr_options_changed();
    init_browse_format_combobox();

    /* For some reason, it did not work to set this via glade        */
    /* So, we have to select our default faraday rotation style here */
    rb_select("rb_fr_global", TRUE);
    polarimetry_settings_changed();

    /* put files on the command-line into the files section */
    populate_files_list(argc, argv);

    /* set up the rgb stuff on the export tab */
    rgb_combo_box_setup();

    /* enters the main GTK loop */
    gtk_main ();

    /* clean up, application has been closed */
    if (settings_on_execute)
        settings_delete(settings_on_execute);

    if (output_directory)
        g_free(output_directory);

    if (current_naming_scheme)
        naming_scheme_delete(current_naming_scheme);

    release_predefined_projections();

    exit (EXIT_SUCCESS);
}
static void
gtk_text_buffer_insert_markup(GtkTextBuffer * buffer, GtkTextIter * iter,
			      const gchar * markup)
{
    PangoAttrIterator *paiter;
    PangoAttrList *attrlist;
    GtkTextMark *mark;
    GError *error = NULL;
    gchar *text;

    g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
    g_return_if_fail(markup != NULL);

    if (*markup == '\000')
	return;

    /* invalid */
    if (!pango_parse_markup(markup, -1, 0, &attrlist, &text, NULL, &error)) {
	g_warning("Invalid markup string: %s", error->message);
	g_error_free(error);
	return;
    }

    /* trivial, no markup */
    if (attrlist == NULL) {
	gtk_text_buffer_insert(buffer, iter, text, -1);
	g_free(text);
	return;
    }

    /* create mark with right gravity */
    mark = gtk_text_buffer_create_mark(buffer, NULL, iter, FALSE);
    paiter = pango_attr_list_get_iterator(attrlist);

    do {
	PangoAttribute *attr;
	GtkTextTag *tag;
	GtkTextTag *tag_para;
	gint start, end;

	pango_attr_iterator_range(paiter, &start, &end);

	if (end == G_MAXINT)	/* last chunk */
	    end = start - 1;	/* resulting in -1 to be passed to _insert */

	tag = gtk_text_tag_new(NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_LANGUAGE)))
	    g_object_set(tag, "language",
			 pango_language_to_string(((PangoAttrLanguage *)
						   attr)->value), NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_FAMILY)))
	    g_object_set(tag, "family", ((PangoAttrString *) attr)->value,
			 NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_STYLE)))
	    g_object_set(tag, "style", ((PangoAttrInt *) attr)->value,
			 NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_WEIGHT)))
	    g_object_set(tag, "weight", ((PangoAttrInt *) attr)->value,
			 NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_VARIANT)))
	    g_object_set(tag, "variant", ((PangoAttrInt *) attr)->value,
			 NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_STRETCH)))
	    g_object_set(tag, "stretch", ((PangoAttrInt *) attr)->value,
			 NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_SIZE)))
	    g_object_set(tag, "size", ((PangoAttrInt *) attr)->value,
			 NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_FONT_DESC)))
	    g_object_set(tag, "font-desc",
			 ((PangoAttrFontDesc *) attr)->desc, NULL);

	if ((attr =
	     pango_attr_iterator_get(paiter, PANGO_ATTR_FOREGROUND))) {
	    GdkColor col = { 0,
		((PangoAttrColor *) attr)->color.red,
		((PangoAttrColor *) attr)->color.green,
		((PangoAttrColor *) attr)->color.blue
	    };

	    g_object_set(tag, "foreground-gdk", &col, NULL);
	}

	if ((attr =
	     pango_attr_iterator_get(paiter, PANGO_ATTR_BACKGROUND))) {
	    GdkColor col = { 0,
		((PangoAttrColor *) attr)->color.red,
		((PangoAttrColor *) attr)->color.green,
		((PangoAttrColor *) attr)->color.blue
	    };

	    g_object_set(tag, "background-gdk", &col, NULL);
	}

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_UNDERLINE)))
	    g_object_set(tag, "underline", ((PangoAttrInt *) attr)->value,
			 NULL);

	if ((attr =
	     pango_attr_iterator_get(paiter, PANGO_ATTR_STRIKETHROUGH)))
	    g_object_set(tag, "strikethrough",
			 (gboolean) (((PangoAttrInt *) attr)->value != 0),
			 NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_RISE)))
	    g_object_set(tag, "rise", ((PangoAttrInt *) attr)->value,
			 NULL);

	if ((attr = pango_attr_iterator_get(paiter, PANGO_ATTR_SCALE)))
	    g_object_set(tag, "scale", ((PangoAttrFloat *) attr)->value,
			 NULL);

	gtk_text_tag_table_add(gtk_text_buffer_get_tag_table(buffer), tag);

	tag_para =
	    gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table
				      (buffer), "para");
	gtk_text_buffer_insert_with_tags(buffer, iter, text + start,
					 end - start, tag, tag_para, NULL);

	/* mark had right gravity, so it should be
	 *      at the end of the inserted text now */
	gtk_text_buffer_get_iter_at_mark(buffer, iter, mark);
    } while (pango_attr_iterator_next(paiter));

    gtk_text_buffer_delete_mark(buffer, mark);
    pango_attr_iterator_destroy(paiter);
    pango_attr_list_unref(attrlist);
    g_free(text);
}
Example #13
0
static void
hippo_canvas_text_set_property(GObject         *object,
                               guint            prop_id,
                               const GValue    *value,
                               GParamSpec      *pspec)
{
    HippoCanvasText *text;

    text = HIPPO_CANVAS_TEXT(object);

    switch (prop_id) {
    case PROP_TEXT:
        {
            const char *new_text;
            new_text = g_value_get_string(value);
            if (!(new_text == text->text ||
                  (new_text && text->text && strcmp(new_text, text->text) == 0))) {
                g_free(text->text);
                text->text = g_strdup(new_text);
                hippo_canvas_item_emit_request_changed(HIPPO_CANVAS_ITEM(text));
                hippo_canvas_item_emit_paint_needed(HIPPO_CANVAS_ITEM(text), 0, 0, -1, -1);
            }
        }
        break;
    case PROP_ATTRIBUTES:
        {
            PangoAttrList *attrs = g_value_get_boxed(value);
            if (attrs)
                pango_attr_list_ref(attrs);
            if (text->attributes)
                pango_attr_list_unref(text->attributes);            
            text->attributes = attrs;
            hippo_canvas_item_emit_request_changed(HIPPO_CANVAS_ITEM(text));
            hippo_canvas_item_emit_paint_needed(HIPPO_CANVAS_ITEM(text), 0, 0, -1, -1);
        }
        break;
    case PROP_MARKUP:
        {
            char *text;
            PangoAttrList *attrs;
            GError *error = NULL;

            if (!pango_parse_markup(g_value_get_string(value),
                                    -1,
                                    0,
                                    &attrs,
                                    &text,
                                    NULL,
                                    &error)) {
                g_error("Failed to set markup: %s", error->message);
                return;
            }
            g_object_set(object, "text", text, "attributes", attrs, NULL);
            pango_attr_list_unref(attrs);
            g_free(text);
        }
        break;
    case PROP_FONT_SCALE:
        text->font_scale = g_value_get_double(value);
        hippo_canvas_item_emit_request_changed(HIPPO_CANVAS_ITEM(text));
        hippo_canvas_item_emit_paint_needed(HIPPO_CANVAS_ITEM(text), 0, 0, -1, -1);
        break;
    case PROP_SIZE_MODE:
        text->size_mode = g_value_get_enum(value);
        hippo_canvas_item_emit_request_changed(HIPPO_CANVAS_ITEM(text));
        hippo_canvas_item_emit_paint_needed(HIPPO_CANVAS_ITEM(text), 0, 0, -1, -1);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
        break;
    }
}
Example #14
0
static boolean pango_textlayout(textspan_t * span, char **fontpath)
{
    static char buf[1024];  /* returned in fontpath, only good until next call */
    static PangoFontMap *fontmap;
    static PangoContext *context;
    static PangoFontDescription *desc;
    static char *fontname;
    static double fontsize;
    static gv_font_map* gv_fmap;
    char *fnt, *psfnt = NULL;
    PangoLayout *layout;
    PangoRectangle logical_rect;
    cairo_font_options_t* options;
    PangoFont *font;
#ifdef ENABLE_PANGO_MARKUP
    PangoAttrList *attrs;
    GError *error = NULL;
    int flags;
#endif
    char *text;
    double textlayout_scale;
    PostscriptAlias *pA;

    if (!context) {
	fontmap = pango_cairo_font_map_new();
	gv_fmap = get_font_mapping(fontmap);
#ifdef HAVE_PANGO_FONT_MAP_CREATE_CONTEXT
	context = pango_font_map_create_context (fontmap);
#else
	context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
#endif
	options=cairo_font_options_create();
	cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
	cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
	pango_cairo_context_set_font_options(context, options);
	pango_cairo_context_set_resolution(context, FONT_DPI);
	cairo_font_options_destroy(options);
	g_object_unref(fontmap);
    }

    if (!fontname || strcmp(fontname, span->font->name) != 0 || fontsize != span->font->size) {
	fontname = span->font->name;
	fontsize = span->font->size;
	pango_font_description_free (desc);

	pA = span->font->postscript_alias;
	if (pA) {
	    psfnt = fnt = gv_fmap[pA->xfig_code].gv_font;
	    if(!psfnt)
		psfnt = fnt = pango_psfontResolve (pA);
	}
	else
	    fnt = fontname;

	desc = pango_font_description_from_string(fnt);
        /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */
        pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE));

        if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) {  /* -v support */
	    const char *fontclass;

	    fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font));

	    buf[0] = '\0';
	    if (psfnt) {
		strcat(buf, "(ps:pango  ");
		strcat(buf, psfnt);
		strcat(buf, ") ");
	    }
	    strcat(buf, "(");
	    strcat(buf, fontclass);
	    strcat(buf, ") ");
#ifdef HAVE_PANGO_FC_FONT_LOCK_FACE
	    if (strcmp(fontclass, "PangoCairoFcFont") == 0) {
	        FT_Face face;
	        PangoFcFont *fcfont;
	        FT_Stream stream;
	        FT_StreamDesc streamdesc;
	        fcfont = PANGO_FC_FONT(font);
	        face = pango_fc_font_lock_face(fcfont);
	        if (face) {
		    strcat(buf, "\"");
		    strcat(buf, face->family_name);
		    strcat(buf, ", ");
		    strcat(buf, face->style_name);
		    strcat(buf, "\" ");
    
		    stream = face->stream;
		    if (stream) {
			streamdesc = stream->pathname;
			if (streamdesc.pointer)
			    strcat(buf, (char*)streamdesc.pointer);
		        else
			    strcat(buf, "*no pathname available*");
		    }
		    else
			strcat(buf, "*no stream available*");
		}
	        pango_fc_font_unlock_face(fcfont);
	    }
	    else
#endif
	    {
    		PangoFontDescription *tdesc;
		char *tfont;
		
	        tdesc = pango_font_describe(font);
	        tfont = pango_font_description_to_string(tdesc);
	        strcat(buf, "\"");
	        strcat(buf, tfont);
	        strcat(buf, "\" ");
	        g_free(tfont);
	    }
            *fontpath = buf;
        }
    }

#ifdef ENABLE_PANGO_MARKUP
    if ((span->font) && (flags = span->font->flags)) {
	unsigned char buf[BUFSIZ];
	agxbuf xb;

	agxbinit(&xb, BUFSIZ, buf);
	agxbput(&xb,"<span");

	if (flags & HTML_BF)
	    agxbput(&xb," weight=\"bold\"");
	if (flags & HTML_IF)
	    agxbput(&xb," style=\"italic\"");
	if (flags & HTML_UL)
	    agxbput(&xb," underline=\"single\"");
	if (flags & HTML_S)
	    agxbput(&xb," strikethrough=\"true\"");
	agxbput (&xb,">");

	if (flags & HTML_SUP)
	    agxbput(&xb,"<sup>");
	if (flags & HTML_SUB)
	    agxbput(&xb,"<sub>");

	agxbput (&xb,xml_string0(span->str, TRUE));

	if (flags & HTML_SUB)
	    agxbput(&xb,"</sub>");
	if (flags & HTML_SUP)
	    agxbput(&xb,"</sup>");

	agxbput (&xb,"</span>");
	if (!pango_parse_markup (agxbuse(&xb), -1, 0, &attrs, &text, NULL, &error)) {
	    fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message);
	    text = span->str;
	    attrs = NULL;
	}
	agxbfree (&xb);
    }
    else {
	text = span->str;
	attrs = NULL;
    }
#else
    text = span->str;
#endif

    layout = pango_layout_new (context);
    span->layout = (void *)layout;    /* layout free with textspan - see labels.c */
    span->free_layout = pango_free_layout;    /* function for freeing pango layout */

    pango_layout_set_text (layout, text, -1);
    pango_layout_set_font_description (layout, desc);
#ifdef ENABLE_PANGO_MARKUP
    if (attrs)
	pango_layout_set_attributes (layout, attrs);
#endif

    pango_layout_get_extents (layout, NULL, &logical_rect);

    /* if pango doesn't like the font then it sets width=0 but height = garbage */
    if (logical_rect.width == 0)
	logical_rect.height = 0;

    textlayout_scale = POINTS_PER_INCH / (FONT_DPI * PANGO_SCALE);
    span->size.x = (int)(logical_rect.width * textlayout_scale + 1);    /* round up so that width/height are never too small */
    span->size.y = (int)(logical_rect.height * textlayout_scale + 1);

    /* FIXME  -- Horrible kluge !!! */

    /* For now we are using pango for single line blocks only.
     * The logical_rect.height seems to be too high from the font metrics on some platforms.
     * Use an assumed height based on the point size.
     */

    span->size.y = (int)(span->font->size * 1.1 + .5);

    /* The y offset from baseline to 0,0 of the bitmap representation */
#if !defined(WIN32) && defined PANGO_VERSION_MAJOR && (PANGO_VERSION_MAJOR >= 1)
    span->yoffset_layout = pango_layout_get_baseline (layout) * textlayout_scale;
#else
    {
	/* do it the hard way on rhel5/centos5 */
	PangoLayoutIter *iter = pango_layout_get_iter (layout);
	span->yoffset_layout = pango_layout_iter_get_baseline (iter) * textlayout_scale;
    }
#endif

    /* The distance below midline for y centering of text strings */
    span->yoffset_centerline = 0.2 * span->font->size;

    if (logical_rect.width == 0)
	return FALSE;
    return TRUE;
}