⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtklabel.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 2 页
字号:
  GtkLabelWord *word, **tailp;  gint space_width, line_width, max_line_width;  GdkWChar *str, *p;    gtk_label_free_words (label);  if (label->label == NULL)    return 0;    /* Split text at new-lines.  (Or at spaces in the case of paragraphs). */  space_width = gdk_string_width (GTK_WIDGET (label)->style->font, " ");    line_width = 0;  max_line_width = 0;  tailp = &label->words;  str = label->label_wc;  while (*str)    {      word = gtk_label_word_alloc ();            if (str == label->label_wc || str[-1] == '\n')	{	  /* Paragraph break */	  word->space = 0;	  	  max_line_width = MAX (line_width, max_line_width);	  line_width = 0;	}      else if (str[0] == ' ')	{	  gint nspaces = 0;	  	  while (str[0] == ' ')	    {	      nspaces++;	      str++;	    }	  	  if (label->jtype == GTK_JUSTIFY_FILL)	    word->space = (space_width * 3 + 1) / 2;	  else	    word->space = space_width * nspaces;	}      else	{	  /* Regular inter-word space */	  word->space = space_width;	}            word->beginning = str;      word->length = 0;      p = word->beginning;      while (*p && !gdk_iswspace (*p))	{	  word->length++;	  p++;	}      word->width = gdk_text_width_wc (GTK_WIDGET (label)->style->font, str, word->length);            str += word->length;      if (*str)	str++;            line_width += word->space + word->width;            *tailp = word;      tailp = &word->next;    }    return MAX (line_width, max_line_width);}/* gtk_label_pick_width * * Split paragraphs, trying to make each line at least min_width, * and trying even harder to make each line no longer than max_width. * * Returns the length of the longest resulting line. * * (The reason we go to all this effort to pick a paragraph width is to * try to avoid the lame look of a short paragraph with a * short final line.) */static gintgtk_label_pick_width (GtkLabel *label,		      gint      min_width,		      gint      max_width){  GtkLabelWord *word;  gint width, line_width;    g_return_val_if_fail (label->wrap, min_width);    line_width = 0;  width = 0;  for (word = label->words; word; word = word->next)    {      if (word->space == 0	  || (line_width	      && (line_width >= min_width		  || line_width + word->width + word->space > max_width)))	{	  /* New line */	  width = MAX (width, line_width);	  line_width = 0;	}      line_width += word->space + word->width;    }    return MAX (width, line_width);}/* Here, we finalize the lines. * This is only for non-wrap labels.  Wrapped labels * use gtk_label_finalize_wrap instead. */static voidgtk_label_finalize_lines (GtkLabel       *label,			  GtkRequisition *requisition,			  gint            max_line_width){  GtkLabelWord *line;  gint y, baseline_skip, y_max;  gint i, j;  gchar *ptrn;    g_return_if_fail (!label->wrap);  ptrn = label->pattern;    y = 0;  baseline_skip = (GTK_WIDGET (label)->style->font->ascent +		   GTK_WIDGET (label)->style->font->descent + 2);    for (line = label->words; line; line = line->next)    {      if (label->jtype == GTK_JUSTIFY_CENTER)	line->x = (max_line_width - line->width) / 2;      else if (label->jtype == GTK_JUSTIFY_RIGHT)	line->x = max_line_width - line->width;      else	line->x = 0;            line->y = y + GTK_WIDGET (label)->style->font->ascent + 1;      y_max = 0;            /* now we deal with the underline stuff; */      if (ptrn && ptrn[0] != '\0')	{	  for (i = 0; i < line->length; i++)	    {	      if (ptrn[i] == '\0')		break;	      else if (ptrn[i] == '_')		{		  gint descent;		  gint rbearing;		  gint lbearing;		  gint width;		  gint offset;		  GtkLabelULine *uline;		  		  for (j = i + 1; j < line->length; j++)		    {		      if (ptrn[j] == '\0')			break;		      else if (ptrn[j] == ' ')			break;		    }		  		  /* good.  Now we have an underlined segment.		   * let's measure it and record it.		   */		  offset = gdk_text_width_wc (GTK_WIDGET (label)->style->font,					      line->beginning,					      i);		  gdk_text_extents_wc (GTK_WIDGET (label)->style->font,				       line->beginning+i,				       j-i, &lbearing,				       &rbearing, &width, NULL,				       &descent);		  y_max = MAX (descent + 2, y_max);		  uline = gtk_label_uline_alloc ();		  uline->x1 = offset + line->x + lbearing - 1;		  uline->x2 = offset + line->x + rbearing;		  uline->y = line->y + descent + 2;		  uline->next = line->uline;		  line->uline = uline;		  i = j - 1;		}	    }	  if (strlen (ptrn) > line->length)	    /* the + 1 is for line breaks. */	    ptrn += line->length + 1;	  else	    ptrn = NULL;	}      y += (baseline_skip + y_max);    }    label->max_width = max_line_width;  requisition->width = max_line_width + 2 * label->misc.xpad;  requisition->height = y + 2 * label->misc.ypad;}/* this finalizes word-wrapped words */static voidgtk_label_finalize_lines_wrap (GtkLabel       *label,			       GtkRequisition *requisition,			       gint            max_line_width){  GtkLabelWord *word, *line, *next_line;  GtkWidget *widget;  gchar *ptrn;  gint x, y, space, extra_width, add_space, baseline_skip;    g_return_if_fail (label->wrap);    ptrn = label->pattern;  y = 0;  baseline_skip = (GTK_WIDGET (label)->style->font->ascent +		   GTK_WIDGET (label)->style->font->descent + 1);    for (line = label->words; line != 0; line = next_line)    {      space = 0;      extra_width = max_line_width - line->width;            for (next_line = line->next; next_line; next_line = next_line->next)	{	  if (next_line->space == 0)	    break;		/* New paragraph */	  if (next_line->space + next_line->width > extra_width)	    break;	  extra_width -= next_line->space + next_line->width;	  space += next_line->space;	}            line->x = 0;      line->y = y + GTK_WIDGET (label)->style->font->ascent + 1;      x = line->width;      add_space = 0;            for (word = line->next; word != next_line; word = word->next)	{	  if (next_line && next_line->space)	    {	      /* Not last line of paragraph --- fill line if needed */	      if (label->jtype == GTK_JUSTIFY_FILL) {		add_space = (extra_width * word->space + space / 2) / space;		extra_width -= add_space;		space -= word->space;	      }	    }	  	  word->x = x + word->space + add_space;	  word->y = line->y;	  x = word->x + word->width;	}            y += (baseline_skip);    }    label->max_width = max_line_width;  widget = GTK_WIDGET (label);  requisition->width = max_line_width + 2 * label->misc.xpad;  requisition->height = y + 2 * label->misc.ypad + 1;}static voidgtk_label_size_request (GtkWidget      *widget,			GtkRequisition *requisition){  GtkLabel *label;    g_return_if_fail (GTK_IS_LABEL (widget));  g_return_if_fail (requisition != NULL);    label = GTK_LABEL (widget);  /*   * There are a number of conditions which will necessitate re-filling   * our text:   *   *     1. text changed.   *     2. justification changed either from to to GTK_JUSTIFY_FILL.   *     3. font changed.   *   * These have been detected elsewhere, and label->words will be zero,   * if one of the above has occured.   *   * Additionally, though, if GTK_JUSTIFY_FILL, we need to re-fill if:   *   *     4. gtk_widget_set_usize has changed the requested width.   *     5. gtk_misc_set_padding has changed xpad.   *     6.  maybe others?...   *   * Too much of a pain to detect all these case, so always re-fill.  I   * don't think it's really that slow.   */    if (label->wrap)    {      GtkWidgetAuxInfo *aux_info;      gint longest_paragraph;            longest_paragraph = gtk_label_split_text_wrapped (label);            aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");      if (aux_info && aux_info->width > 0)	{	  label->max_width = MAX (aux_info->width - 2 * label->misc.xpad, 1);	  gtk_label_split_text_wrapped (label);	}      else	{	  label->max_width = gdk_string_width (GTK_WIDGET (label)->style->font,					       "This is a good enough length for any line to have.");	  label->max_width = MIN (label->max_width, (gdk_screen_width () + 1) / 2);	  label->max_width = MIN (label->max_width, longest_paragraph);	  if (longest_paragraph > 0)	    {	      gint nlines, perfect_width;	      	      nlines = (longest_paragraph + label->max_width - 1) / label->max_width;	      perfect_width = (longest_paragraph + nlines - 1) / nlines;	      label->max_width = gtk_label_pick_width (label,						       perfect_width,						       label->max_width);	    }	}      gtk_label_finalize_lines_wrap (label, requisition, label->max_width);    }  else if (!label->words)    {      label->max_width = gtk_label_split_text (label);      gtk_label_finalize_lines (label, requisition, label->max_width);    }}static void gtk_label_style_set (GtkWidget *widget,		     GtkStyle  *previous_style){  GtkLabel *label;  g_return_if_fail (GTK_IS_LABEL (widget));    label = GTK_LABEL (widget);    /* Clear the list of words so that they are recomputed on   * size_request   */  if (previous_style && label->words)    gtk_label_free_words (label);}static voidgtk_label_paint_word (GtkLabel     *label,		      gint          x,		      gint          y,		      GtkLabelWord *word,		      GdkRectangle *area){  GtkWidget *widget = GTK_WIDGET (label);  GtkLabelULine *uline;  gchar *tmp_str;    tmp_str = gdk_wcstombs (word->beginning);  if (tmp_str)    {      gtk_paint_string (widget->style, widget->window, widget->state,			area, widget, "label", 			x + word->x,			y + word->y,			tmp_str);      g_free (tmp_str);    }    for (uline = word->uline; uline; uline = uline->next)    gtk_paint_hline (widget->style, widget->window, 		     widget->state, area,		     widget, "label", 		     x + uline->x1, x + uline->x2, y + uline->y);}static gintgtk_label_expose (GtkWidget      *widget,		  GdkEventExpose *event){  GtkLabel *label;  GtkMisc *misc;  GtkLabelWord *word;  gint x, y;    g_return_val_if_fail (GTK_IS_LABEL (widget), FALSE);  g_return_val_if_fail (event != NULL, FALSE);    label = GTK_LABEL (widget);    if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) &&      label->label && (*label->label != '\0'))    {      misc = GTK_MISC (widget);            /*       * GC Clipping       */      gdk_gc_set_clip_rectangle (widget->style->white_gc, &event->area);      gdk_gc_set_clip_rectangle (widget->style->fg_gc[widget->state], &event->area);            x = floor (widget->allocation.x + (gint)misc->xpad		 + (((gint)widget->allocation.width - 		    (gint)label->max_width - 2 * (gint)misc->xpad)		    * misc->xalign) + 0.5);            y = floor (widget->allocation.y + (gint)misc->ypad 		 + (((gint)widget->allocation.height		     - (gint)widget->requisition.height)		    * misc->yalign) + 0.5);      for (word = label->words; word; word = word->next)	{	  gchar save = word->beginning[word->length];	  word->beginning[word->length] = '\0';	  gtk_label_paint_word (label, x, y, word, &event->area);	  word->beginning[word->length] = save;	}            gdk_gc_set_clip_mask (widget->style->white_gc, NULL);      gdk_gc_set_clip_mask (widget->style->fg_gc[widget->state], NULL);    }  return TRUE;}guint      gtk_label_parse_uline (GtkLabel    *label,		       const gchar *string){  guint accel_key = GDK_VoidSymbol;  GdkWChar *p, *q, *string_wc;  gchar *r;  gchar *pattern;  gint length, wc_length;  gboolean underscore;    g_return_val_if_fail (GTK_IS_LABEL (label), GDK_VoidSymbol);  g_return_val_if_fail (string != NULL, GDK_VoidSymbol);  /* Convert text to wide characters */  length = strlen (string);  string_wc = g_new (GdkWChar, length + 1);  wc_length = gdk_mbstowcs (string_wc, string, length + 1);  if (wc_length < 0)    {      g_free (string_wc);      return GDK_VoidSymbol;    }  string_wc[wc_length] = '\0';    pattern = g_new (gchar, length+1);    underscore = FALSE;    p = q = string_wc;  r = pattern;    while (*p)    {      if (underscore)	{	  if (*p == '_')	    *r++ = ' ';	  else	    {	      *r++ = '_';	      if (accel_key == GDK_VoidSymbol)		accel_key = gdk_keyval_to_lower (*p);	    }	  	  *q++ = *p;	  underscore = FALSE;	}      else	{	  if (*p == '_')	    underscore = TRUE;	  else	    {	      *q++ = *p;	      *r++ = ' ';	    }	}      p++;    }  *q = 0;  *r = 0;    gtk_label_set_text_internal (label, gdk_wcstombs (string_wc), string_wc);  gtk_label_set_pattern (label, pattern);    g_free (pattern);    return accel_key;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -