Exemplo n.º 1
0
static void
gimp_combo_tag_entry_style_set (GtkWidget *widget,
                                GtkStyle  *previous_style)
{
  GimpComboTagEntry *entry = GIMP_COMBO_TAG_ENTRY (widget);
  GtkStyle          *style = gtk_widget_get_style (widget);
  GdkColor           color;
  PangoAttribute    *attribute;

  if (GTK_WIDGET_CLASS (parent_class)->style_set)
    GTK_WIDGET_CLASS (parent_class)->style_set (widget, previous_style);

  if (entry->normal_item_attr)
    pango_attr_list_unref (entry->normal_item_attr);
  entry->normal_item_attr = pango_attr_list_new ();

  if (style->font_desc)
    {
      attribute = pango_attr_font_desc_new (style->font_desc);
      pango_attr_list_insert (entry->normal_item_attr, attribute);
    }
  color = style->text[GTK_STATE_NORMAL];
  attribute = pango_attr_foreground_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->normal_item_attr, attribute);

  if (entry->selected_item_attr)
    pango_attr_list_unref (entry->selected_item_attr);
  entry->selected_item_attr = pango_attr_list_copy (entry->normal_item_attr);

  color = style->text[GTK_STATE_SELECTED];
  attribute = pango_attr_foreground_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->selected_item_attr, attribute);
  color = style->base[GTK_STATE_SELECTED];
  attribute = pango_attr_background_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->selected_item_attr, attribute);

  if (entry->insensitive_item_attr)
    pango_attr_list_unref (entry->insensitive_item_attr);
  entry->insensitive_item_attr = pango_attr_list_copy (entry->normal_item_attr);

  color = style->text[GTK_STATE_INSENSITIVE];
  attribute = pango_attr_foreground_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->insensitive_item_attr, attribute);
  color = style->base[GTK_STATE_INSENSITIVE];
  attribute = pango_attr_background_new (color.red, color.green, color.blue);
  pango_attr_list_insert (entry->insensitive_item_attr, attribute);

  entry->selected_item_color = style->base[GTK_STATE_SELECTED];

  if (entry->arrow_pixbuf)
    {
      g_object_unref (entry->arrow_pixbuf);
      entry->arrow_pixbuf = NULL;
    }
}
Exemplo n.º 2
0
static void
match_label_color (GstyleColorWidget *self,
                   GstyleColor       *color)
{
  PangoLayout *layout;
  PangoAttrList *attr_list;
  PangoAttribute *attr;
  GdkRGBA rgba;
  GdkRGBA dst_rgba;

  g_assert (GSTYLE_IS_COLOR_WIDGET (self));
  g_assert (GSTYLE_IS_COLOR (color));

  layout = gtk_label_get_layout (self->label);
  attr_list = pango_layout_get_attributes (layout);
  if (attr_list == NULL)
    {
      attr_list = pango_attr_list_new ();
      gtk_label_set_attributes (self->label, attr_list);
      pango_attr_list_unref (attr_list);
    }

  gstyle_color_fill_rgba (color, &rgba);
  gstyle_utils_get_contrasted_rgba (rgba, &dst_rgba);
  attr = pango_attr_foreground_new (dst_rgba.red * 0xffff, dst_rgba.green * 0xffff, dst_rgba.blue * 0xffff);
  pango_attr_list_change (attr_list, attr);
  attr = pango_attr_background_new (rgba.red * 0xffff, rgba.green * 0xffff, rgba.blue * 0xffff);
  pango_attr_list_change (attr_list, attr);
}
Exemplo n.º 3
0
static void create_cursor_attr()
{
    if (attr_list)
        pango_attr_list_unref(attr_list);

    GdkColor color_bg, color_fg;
    if (hime_win_color_use)
        gdk_color_parse(tsin_cursor_color, &color_bg);
    else
        gdk_color_parse(TSIN_CURSOR_COLOR_DEFAULT, &color_bg);
    gdk_color_parse("white", &color_fg);

    attr_list = pango_attr_list_new ();
    attr_list_blank = pango_attr_list_new ();

    PangoAttribute *blue_bg = pango_attr_background_new(
                                  color_bg.red, color_bg.green, color_bg.blue);
    blue_bg->start_index = 0;
    blue_bg->end_index = 128;
    pango_attr_list_insert (attr_list, blue_bg);

    PangoAttribute *white_fg = pango_attr_foreground_new(
                                   color_fg.red, color_fg.green, color_fg.blue);
    white_fg->start_index = 0;
    white_fg->end_index = 128;
    pango_attr_list_insert (attr_list, white_fg);
}
Exemplo n.º 4
0
static void set_background(CustomData *data) {
    PangoAttrList *attrs;

    attrs = pango_attr_list_new();
    pango_attr_list_insert (attrs, pango_attr_background_new (65535, 0, 0));
    gtk_label_set_attributes(GTK_LABEL (data->timelabel), attrs);
    pango_attr_list_unref (attrs);
}
Exemplo n.º 5
0
static void
text_input_preedit_styling(void *data,
			   struct wl_text_input *text_input,
			   uint32_t index,
			   uint32_t length,
			   uint32_t style)
{
	struct text_entry *entry = data;
	PangoAttribute *attr1 = NULL;
	PangoAttribute *attr2 = NULL;

	if (!entry->preedit_info.attr_list)
		entry->preedit_info.attr_list = pango_attr_list_new();

	switch (style) {
		case WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT:
		case WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE:
			attr1 = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
			break;
		case WL_TEXT_INPUT_PREEDIT_STYLE_INCORRECT:
			attr1 = pango_attr_underline_new(PANGO_UNDERLINE_ERROR);
			attr2 = pango_attr_underline_color_new(65535, 0, 0);
			break;
		case WL_TEXT_INPUT_PREEDIT_STYLE_SELECTION:
			attr1 = pango_attr_background_new(0.3 * 65535, 0.3 * 65535, 65535);
			attr2 = pango_attr_foreground_new(65535, 65535, 65535);
			break;
		case WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT:
		case WL_TEXT_INPUT_PREEDIT_STYLE_ACTIVE:
			attr1 = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
			attr2 = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
			break;
		case WL_TEXT_INPUT_PREEDIT_STYLE_INACTIVE:
			attr1 = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
			attr2 = pango_attr_foreground_new(0.3 * 65535, 0.3 * 65535, 0.3 * 65535);
			break;
	}

	if (attr1) {
		attr1->start_index = entry->cursor + index;
		attr1->end_index = entry->cursor + index + length;
		pango_attr_list_insert(entry->preedit_info.attr_list, attr1);
	}

	if (attr2) {
		attr2->start_index = entry->cursor + index;
		attr2->end_index = entry->cursor + index + length;
		pango_attr_list_insert(entry->preedit_info.attr_list, attr2);
	}
}
Exemplo n.º 6
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);
}
void scim_bridge_client_imcontext_set_preedit_attributes (ScimBridgeClientIMContext *imcontext, ScimBridgeAttribute** const preedit_attributes, int attribute_count)
{   
    if (imcontext->preedit_attributes != NULL)
        pango_attr_list_unref (imcontext->preedit_attributes);
    
    imcontext->preedit_attributes = pango_attr_list_new ();
    
    int preedit_string_length = 0;
    int preedit_wstring_length = 0;
    if (imcontext->preedit_string != NULL) {
        preedit_string_length = strlen (imcontext->preedit_string);
        preedit_wstring_length = g_utf8_strlen (imcontext->preedit_string, -1);
    }
    
    boolean *has_attribute = alloca (sizeof (boolean) * preedit_string_length);
    int i;
    for (i = 0; i < preedit_string_length; ++i) {
        has_attribute[i] = FALSE;
    }

    for (i = 0; i < attribute_count; ++i) {
        const ScimBridgeAttribute *attr = preedit_attributes[i];
        const int begin_pos = scim_bridge_attribute_get_begin (attr);
        const int end_pos = scim_bridge_attribute_get_end (attr);

        if (begin_pos <= end_pos && 0 <= begin_pos && end_pos <= preedit_wstring_length) {
            const int start_index = g_utf8_offset_to_pointer (imcontext->preedit_string, begin_pos) - imcontext->preedit_string;
            const int end_index = g_utf8_offset_to_pointer (imcontext->preedit_string, end_pos) - imcontext->preedit_string;

            const scim_bridge_attribute_type_t attr_type = scim_bridge_attribute_get_type (attr);
            const scim_bridge_attribute_value_t attr_value = scim_bridge_attribute_get_value (attr);

            boolean valid_attribute = FALSE;
            if (attr_type == ATTRIBUTE_DECORATE) {
                if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_UNDERLINE) {
                    valid_attribute = TRUE;

                    PangoAttribute *pango_attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
                    pango_attr->start_index = start_index;
                    pango_attr->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr);
                } else if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_REVERSE) {
                    valid_attribute = TRUE;

                    PangoAttribute *pango_attr0 = pango_attr_foreground_new (preedit_normal_background.red, preedit_normal_background.green, preedit_normal_background.blue);
                    pango_attr0->start_index = start_index;
                    pango_attr0->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr0);

                    PangoAttribute *pango_attr1 = pango_attr_background_new (preedit_normal_foreground.red, preedit_normal_foreground.green, preedit_normal_foreground.blue);
                    pango_attr1->start_index = start_index;
                    pango_attr1->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr1);
                } else if (attr_value == SCIM_BRIDGE_ATTRIBUTE_DECORATE_HIGHLIGHT) {
                    valid_attribute = TRUE;

                    PangoAttribute *pango_attr0 = pango_attr_foreground_new (preedit_active_foreground.red, preedit_active_foreground.green, preedit_active_foreground.blue);
                    pango_attr0->start_index = start_index;
                    pango_attr0->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr0);

                    PangoAttribute *pango_attr1 = pango_attr_background_new (preedit_active_background.red, preedit_active_background.green, preedit_active_background.blue);
                    pango_attr1->start_index = start_index;
                    pango_attr1->end_index = end_index;
                    pango_attr_list_insert (imcontext->preedit_attributes, pango_attr1);
                } else {
                    scim_bridge_perrorln ("Unknown preedit decoration!");
                }
            } else if (attr_type == ATTRIBUTE_FOREGROUND) {
                valid_attribute = TRUE;

                const unsigned int red = scim_bridge_attribute_get_red (attr) * 256;
                const unsigned int green = scim_bridge_attribute_get_green (attr) * 256;
                const unsigned int blue = scim_bridge_attribute_get_blue (attr) * 256;

                PangoAttribute *pango_attr = pango_attr_foreground_new (red, green, blue);
                pango_attr->start_index = start_index;
                pango_attr->end_index = end_index;
                pango_attr_list_insert (imcontext->preedit_attributes, pango_attr);
            } else if (attr_type == ATTRIBUTE_BACKGROUND) {
                valid_attribute = TRUE;

                const unsigned int red = scim_bridge_attribute_get_red (attr) * 256;
                const unsigned int green = scim_bridge_attribute_get_green (attr) * 256;
                const unsigned int blue = scim_bridge_attribute_get_blue (attr) * 256;

                PangoAttribute *pango_attr = pango_attr_background_new (red, green, blue);
                pango_attr->start_index = start_index;
                pango_attr->end_index = end_index;
                pango_attr_list_insert (imcontext->preedit_attributes, pango_attr);
            }

            if (valid_attribute) {
                int j;
                for (j = start_index; j < end_index; ++j) {
                    has_attribute[j] = TRUE;
                }
            }
        }

    }

    // Add underlines for the all characters without attributes.
    for (i = 0; i < preedit_string_length; ++i) {
        if (has_attribute[i] == FALSE) {
            PangoAttribute *pango_attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
            pango_attr->start_index = i;
            for (; i < preedit_string_length && has_attribute[i] == FALSE; ++i);
            pango_attr->end_index = i;
            pango_attr_list_insert (imcontext->preedit_attributes, pango_attr);
        }
    }
}
Exemplo n.º 8
0
static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context,
					  gint page_nr, gpointer user_data)
{
	DocInfo *dinfo = user_data;
	GeanyEditor *editor;
	cairo_t *cr;
	gdouble width, height;
	gdouble x = 0.0, y = 0.0;
	/*gint layout_h;*/
	gint count;
	GString *str;

	if (dinfo == NULL || page_nr >= dinfo->n_pages)
		return;

	editor = dinfo->doc->editor;

	if (dinfo->n_pages > 0)
	{
		gdouble fraction = (page_nr + 1) / (gdouble) dinfo->n_pages;
		gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr, dinfo->n_pages);
		gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_widgets.progressbar), fraction);
		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text);
		g_free(text);
	}

#ifdef GEANY_PRINT_DEBUG
	geany_debug("draw_page = %d, pages = %d, (real) lines_per_page = %d",
		page_nr, dinfo->n_pages, dinfo->lines_per_page);
#endif

	str = g_string_sized_new(256);
	cr = gtk_print_context_get_cairo_context(context);
	width = gtk_print_context_get_width(context);
	height = gtk_print_context_get_height(context);

	cairo_set_source_rgb(cr, 0, 0, 0);
#ifdef GEANY_PRINT_DEBUG
	cairo_set_line_width(cr, 0.2);
	cairo_rectangle(cr, 0, 0, width, height);
	cairo_stroke(cr);
#endif
	cairo_move_to(cr, 0, 0);

	pango_layout_set_width(dinfo->layout, width * PANGO_SCALE);
	pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_LEFT);
	pango_layout_set_ellipsize(dinfo->layout, FALSE);
	pango_layout_set_justify(dinfo->layout, FALSE);

	if (printing_prefs.print_page_header)
		add_page_header(dinfo, cr, width, page_nr);

	count = 0;	/* the actual line counter for the current page, might be different from
				 * dinfo->cur_line due to possible line breaks */
	while (count < dinfo->lines_per_page)
	{
		gchar c = 'a';
		gint style = -1;
		PangoAttrList *layout_attr;
		PangoAttribute *attr;
		gint colours[3] = { 0 };
		gboolean add_linenumber = TRUE;
		gboolean at_eol;

		while (count < dinfo->lines_per_page && c != '\0')
		{
			at_eol = FALSE;

			g_string_erase(str, 0, str->len); /* clear the string */

			/* line numbers */
			if (printing_prefs.print_line_numbers && add_linenumber)
			{
				/* if we had a wrapped line on the last page which needs to be continued, don't
				 * add a line number */
				if (dinfo->long_line)
				{
					add_linenumber = FALSE;
				}
				else
				{
					gchar *line_number = NULL;
					gint cur_line_number_margin = get_line_numbers_arity(dinfo->cur_line + 1);
					gchar *fill = g_strnfill(
						dinfo->max_line_number_margin - cur_line_number_margin - 1, ' ');

					line_number = g_strdup_printf("%s%d ", fill, dinfo->cur_line + 1);
					g_string_append(str, line_number);
					dinfo->cur_line++; /* increase document line */
					add_linenumber = FALSE;
					style = STYLE_LINENUMBER;
					c = 'a'; /* dummy value */
					g_free(fill);
					g_free(line_number);
				}
			}
			/* data */
			else
			{
				style = sci_get_style_at(dinfo->doc->editor->sci, dinfo->cur_pos);
				c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
				if (c == '\0' || style == -1)
				{	/* if c gets 0, we are probably out of document boundaries,
					 * so stop to break out of outer loop */
					count = dinfo->lines_per_page;
					break;
				}
				dinfo->cur_pos++;

				/* convert tabs to spaces which seems to be better than using Pango tabs */
				if (c == '\t')
				{
					gint tab_width = sci_get_tab_width(editor->sci);
					gchar *s = g_strnfill(tab_width, ' ');
					g_string_append(str, s);
					g_free(s);
				}
				/* don't add line breaks, they are handled manually below */
				else if (c == '\r' || c == '\n')
				{
					gchar c_next = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
					at_eol = TRUE;
					if (c == '\r' && c_next == '\n')
						dinfo->cur_pos++; /* skip LF part of CR/LF */
				}
				else
				{
					g_string_append_c(str, c); /* finally add the character */

					/* handle UTF-8: since we add char by char (better: byte by byte), we need to
					 * keep UTF-8 characters together(e.g. two bytes for one character)
					 * the input is always UTF-8 and c is signed, so all non-Ascii
					 * characters are less than 0 and consist of all bytes less than 0.
					 * style doesn't change since it is only one character with multiple bytes. */
					while (c < 0)
					{
						c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
						if (c < 0)
						{	/* only add the byte when it is part of the UTF-8 character
							 * otherwise we could add e.g. a '\n' and it won't be visible in the
							 * printed document */
							g_string_append_c(str, c);
							dinfo->cur_pos++;
						}
					}
				}
			}

			if (! at_eol)
			{
				/* set text */
				pango_layout_set_text(dinfo->layout, str->str, -1);
				/* attributes */
				layout_attr = pango_attr_list_new();
				/* foreground colour */
				get_rgb_values(dinfo->styles[style][FORE], &colours[0], &colours[1], &colours[2]);
				attr = pango_attr_foreground_new(colours[0], colours[1], colours[2]);
				ADD_ATTR(layout_attr, attr);
				/* background colour */
				get_rgb_values(dinfo->styles[style][BACK], &colours[0], &colours[1], &colours[2]);
				attr = pango_attr_background_new(colours[0], colours[1], colours[2]);
				ADD_ATTR(layout_attr, attr);
				/* bold text */
				if (dinfo->styles[style][BOLD])
				{
					attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
					ADD_ATTR(layout_attr, attr);
				}
				/* italic text */
				if (dinfo->styles[style][ITALIC])
				{
					attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
					ADD_ATTR(layout_attr, attr);
				}
				pango_layout_set_attributes(dinfo->layout, layout_attr);
				pango_layout_context_changed(dinfo->layout);
				pango_attr_list_unref(layout_attr);
			}

			cairo_get_current_point(cr, &x, &y);


			/* normal line break at eol character in document */
			if (at_eol)
			{
				/*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/
				/*cairo_move_to(cr, 0, y + (gdouble)layout_h / PANGO_SCALE);*/
				cairo_move_to(cr, 0, y + dinfo->line_height);

				count++;
				/* we added a new document line so request a new line number */
				add_linenumber = TRUE;
			}
			else
			{
				gint x_offset = 0;
				/* maybe we need to force a line break because of too long line */
				if (x >= (width - dinfo->font_width))
				{
					/* don't start the line at horizontal origin because we need to skip the
					 * line number margin */
					if (printing_prefs.print_line_numbers)
					{
						x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width;
					}

					/*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/
					/*cairo_move_to(cr, x_offset, y + (gdouble)layout_h / PANGO_SCALE);*/
					/* this is faster but not exactly the same as above */
					cairo_move_to(cr, x_offset, y + dinfo->line_height);
					cairo_get_current_point(cr, &x, &y);
					count++;
				}
				if (count < dinfo->lines_per_page)
				{
					/* str->len is counted in bytes not characters, so use g_utf8_strlen() */
					x_offset = (g_utf8_strlen(str->str, -1) * dinfo->font_width);

					if (dinfo->long_line && count == 0)
					{
						x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width;
						dinfo->long_line = FALSE;
					}

					pango_cairo_show_layout(cr, dinfo->layout);
					cairo_move_to(cr, x + x_offset, y);
				}
				else
				/* we are on a wrapped line but we are out of lines on this page, so continue
				 * the current line on the next page and remember to continue in current line */
					dinfo->long_line = TRUE;
			}
		}
	}

	if (printing_prefs.print_line_numbers)
	{	/* print a thin line between the line number margin and the data */
		gint y_start = 0;

		if (printing_prefs.print_page_header)
			y_start = (dinfo->line_height * 3) - 2;	/* "- 2": to connect the line number line to
													 * the page header frame */

		cairo_set_line_width(cr, 0.3);
		cairo_move_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y_start);
		cairo_line_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1,
			y + dinfo->line_height); /* y is last added line, we reuse it */
		cairo_stroke(cr);
	}

	if (printing_prefs.print_page_numbers)
	{
		gchar *line = g_strdup_printf("<small>- %d -</small>", page_nr + 1);
		pango_layout_set_markup(dinfo->layout, line, -1);
		pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_CENTER);
		cairo_move_to(cr, 0, height - dinfo->line_height);
		pango_cairo_show_layout(cr, dinfo->layout);
		g_free(line);

#ifdef GEANY_PRINT_DEBUG
		cairo_set_line_width(cr, 0.3);
		cairo_move_to(cr, 0, height - (1.25 * dinfo->line_height));
		cairo_line_to(cr, width - 1, height - (1.25 * dinfo->line_height));
		cairo_stroke(cr);
#endif
	}
	g_string_free(str, TRUE);
}
Exemplo n.º 9
0
static void
text_entry_update_layout(struct text_entry *entry)
{
	char *text;
	PangoAttrList *attr_list;

	assert(entry->cursor <= (strlen(entry->text) +
	       (entry->preedit.text ? strlen(entry->preedit.text) : 0)));

	if (entry->preedit.text) {
		text = malloc(strlen(entry->text) + strlen(entry->preedit.text) + 1);
		strncpy(text, entry->text, entry->cursor);
		strcpy(text + entry->cursor, entry->preedit.text);
		strcpy(text + entry->cursor + strlen(entry->preedit.text),
		       entry->text + entry->cursor);
	} else {
		text = strdup(entry->text);
	}

	if (entry->cursor != entry->anchor) {
		int start_index = MIN(entry->cursor, entry->anchor);
		int end_index = MAX(entry->cursor, entry->anchor);
		PangoAttribute *attr;

		attr_list = pango_attr_list_copy(entry->preedit.attr_list);

		if (!attr_list)
			attr_list = pango_attr_list_new();

		attr = pango_attr_background_new(0.3 * 65535, 0.3 * 65535, 65535);
		attr->start_index = start_index;
		attr->end_index = end_index;
		pango_attr_list_insert(attr_list, attr);

		attr = pango_attr_foreground_new(65535, 65535, 65535);
		attr->start_index = start_index;
		attr->end_index = end_index;
		pango_attr_list_insert(attr_list, attr);
	} else {
		attr_list = pango_attr_list_ref(entry->preedit.attr_list);
	}

	if (entry->preedit.text && !entry->preedit.attr_list) {
		PangoAttribute *attr;

		if (!attr_list)
			attr_list = pango_attr_list_new();

		attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
		attr->start_index = entry->cursor;
		attr->end_index = entry->cursor + strlen(entry->preedit.text);
		pango_attr_list_insert(attr_list, attr);
	}

	if (entry->layout) {
		pango_layout_set_text(entry->layout, text, -1);
		pango_layout_set_attributes(entry->layout, attr_list);
	}

	free(text);
	pango_attr_list_unref(attr_list);
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
static void
_fcitx_im_context_update_formatted_preedit_cb(FcitxClient* im, GPtrArray* array, int cursor_pos, void* user_data)
{
    FcitxLog(LOG_LEVEL, "_fcitx_im_context_commit_string_cb");
    FcitxIMContext* context =  FCITX_IM_CONTEXT(user_data);

    gboolean visible = false;

    if (context->preedit_string != NULL) {
        if (strlen(context->preedit_string) != 0)
            visible = true;
        g_free(context->preedit_string);
        context->preedit_string = NULL;
    }

    if (context->attrlist != NULL) {
        pango_attr_list_unref(context->attrlist);
    }

    context->attrlist = pango_attr_list_new();

    GString* gstr = g_string_new(NULL);

    int i = 0;
    for (i = 0; i < array->len; i++) {
        size_t bytelen = strlen(gstr->str);
        FcitxPreeditItem* preedit = g_ptr_array_index(array, i);
        const gchar* s = preedit->string;
        gint type = preedit->type;

        PangoAttribute *pango_attr = NULL;
        if ((type & MSG_NOUNDERLINE) == 0) {
            pango_attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
            pango_attr->start_index = bytelen;
            pango_attr->end_index = bytelen + strlen(s);
            pango_attr_list_insert(context->attrlist, pango_attr);
        }

        if (type & MSG_HIGHLIGHT) {
            gboolean hasColor;
            GdkColor fg;
            GdkColor bg;

            if (context->client_window) {
                GtkWidget *widget;
                gdk_window_get_user_data (context->client_window,
                                          (gpointer *)&widget);
                if (GTK_IS_WIDGET(widget)) {
                    hasColor = true;
                    GtkStyle* style = gtk_widget_get_style(widget);
                    fg = style->text[GTK_STATE_SELECTED];
                    bg = style->bg[GTK_STATE_SELECTED];
                }
            }

            if (!hasColor) {
                fg.red = 0xffff;
                fg.green = 0xffff;
                fg.blue = 0xffff;
                bg.red = 0x43ff;
                bg.green = 0xacff;
                bg.blue = 0xe8ff;
            }

            pango_attr = pango_attr_foreground_new(fg.red, fg.green, fg.blue);
            pango_attr->start_index = bytelen;
            pango_attr->end_index = bytelen + strlen(s);
            pango_attr_list_insert(context->attrlist, pango_attr);
            pango_attr = pango_attr_background_new(bg.red, bg.green, bg.blue);
            pango_attr->start_index = bytelen;
            pango_attr->end_index = bytelen + strlen(s);
            pango_attr_list_insert(context->attrlist, pango_attr);
        }
        gstr = g_string_append(gstr, s);
    }

    gchar* str = g_string_free(gstr, FALSE);

    context->preedit_string = g_strdup(str);
    char* tempstr = g_strndup(str, cursor_pos);
    context->cursor_pos =  fcitx_utf8_strlen(tempstr);
    g_free(tempstr);

    gboolean new_visible = false;

    if (context->preedit_string != NULL) {
        if (strlen(context->preedit_string) != 0)
            new_visible = true;
    }
    gboolean flag = new_visible != visible;

    if (new_visible) {
        if (flag) {
            /* invisible => visible */
            g_signal_emit(context, _signal_preedit_start_id, 0);
        }
        g_signal_emit(context, _signal_preedit_changed_id, 0);
    } else {
        if (flag) {
            /* visible => invisible */
            g_signal_emit(context, _signal_preedit_changed_id, 0);
            g_signal_emit(context, _signal_preedit_end_id, 0);
        } else {
            /* still invisible */
            /* do nothing */
        }
    }

    g_signal_emit(context, _signal_preedit_changed_id, 0);
}