Beispiel #1
0
static const gchar *
get_sample_string (FT_Face face)
{
    const gchar *text;

    text = pango_language_get_sample_string (NULL);

    if (!check_font_contain_text (face, text)) {
	text = pango_language_get_sample_string (pango_language_from_string ("en_US"));
    }

    return text;
}
Beispiel #2
0
static PangoFontMetrics *
create_metrics_for_context (PangoFont    *font,
			    PangoContext *context)
{
  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
  PangoFontMetrics *metrics;
  PangoFontDescription *font_desc;
  PangoLayout *layout;
  PangoRectangle extents;
  PangoLanguage *language = pango_context_get_language (context);
  const char *sample_str = pango_language_get_sample_string (language);
  cairo_scaled_font_t *scaled_font;
  cairo_font_extents_t font_extents;
  double height;
  
  metrics = pango_font_metrics_new ();
  
  scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (cwfont));

  cairo_scaled_font_extents (scaled_font, &font_extents);
  cairo_win32_scaled_font_done_font (scaled_font);
  
  metrics->ascent = font_extents.ascent * PANGO_SCALE;
  metrics->descent = font_extents.descent * PANGO_SCALE;

  /* FIXME: Should get the real settings for these from the TrueType
   * font file.
   */
  height = metrics->ascent + metrics->descent;
  metrics->underline_thickness = height / 14;
  metrics->underline_position = - metrics->underline_thickness;
  metrics->strikethrough_thickness = metrics->underline_thickness;
  metrics->strikethrough_position = height / 4;

  pango_quantize_line_geometry (&metrics->underline_thickness,
				&metrics->underline_position);
  pango_quantize_line_geometry (&metrics->strikethrough_thickness,
				&metrics->strikethrough_position);

  layout = pango_layout_new (context);
  font_desc = pango_font_describe_with_absolute_size (font);
  pango_layout_set_font_description (layout, font_desc);
  pango_layout_set_text (layout, sample_str, -1);      
  pango_layout_get_extents (layout, NULL, &extents);
  
  metrics->approximate_char_width = extents.width / g_utf8_strlen (sample_str, -1);

  pango_layout_set_text (layout, "0123456789", -1);
  metrics->approximate_digit_width = max_glyph_width (layout);

  pango_font_description_free (font_desc);
  g_object_unref (layout);

  return metrics;
}
Beispiel #3
0
static gboolean
set_pango_sample_string (SushiFontWidget *self)
{
  const gchar *sample_string;
  gboolean retval = FALSE;

  sample_string = pango_language_get_sample_string (pango_language_from_string (NULL));
  if (check_font_contain_text (self->priv->face, sample_string))
    retval = TRUE;

  if (!retval) {
    sample_string = pango_language_get_sample_string (pango_language_from_string ("C"));
    if (check_font_contain_text (self->priv->face, sample_string))
      retval = TRUE;
  }

  if (retval) {
    g_free (self->priv->sample_string);
    self->priv->sample_string = g_strdup (sample_string);
  }

  return retval;
}
Beispiel #4
0
static PangoFontMetrics *
pango_cairo_win32_font_get_metrics (PangoFont        *font,
				    PangoLanguage    *language)
{
  PangoWin32Font *win32font = PANGO_WIN32_FONT (font);
  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
  PangoWin32MetricsInfo *info = NULL; /* Quiet gcc */
  GSList *tmp_list;      
  const char *sample_str = pango_language_get_sample_string (language);
  
  tmp_list = cwfont->metrics_by_lang;
  while (tmp_list)
    {
      info = tmp_list->data;
      
      if (info->sample_str == sample_str)    /* We _don't_ need strcmp */
	break;

      tmp_list = tmp_list->next;
    }

  if (!tmp_list)
    {
      PangoContext *context;

      if (!win32font->fontmap)
	return pango_font_metrics_new ();

      info = g_slice_new0 (PangoWin32MetricsInfo);
      
      cwfont->metrics_by_lang = g_slist_prepend (cwfont->metrics_by_lang, 
						 info);
	
      info->sample_str = sample_str;

      context = pango_context_new ();
      pango_context_set_font_map (context, win32font->fontmap);
      pango_context_set_language (context, language);
      pango_cairo_context_set_font_options (context, cwfont->options);

      info->metrics = create_metrics_for_context (font, context);

      g_object_unref (context);
    }

  return pango_font_metrics_ref (info->metrics);
}
static PangoFontMetrics *
pango_cairo_core_text_font_create_base_metrics_for_context (PangoCairoFont *font,
                                                            PangoContext   *context)
{
  PangoCoreTextFont *cfont = (PangoCoreTextFont *) font;
  PangoFontMetrics *metrics;
  PangoFontDescription *font_desc;
  PangoLayout *layout;
  PangoRectangle extents;
  PangoLanguage *language = pango_context_get_language (context);
  const char *sample_str = pango_language_get_sample_string (language);
  CTFontRef ctfont;

  metrics = pango_font_metrics_new ();

  ctfont = pango_core_text_font_get_ctfont (cfont);

  metrics->ascent = CTFontGetAscent (ctfont) * PANGO_SCALE;
  metrics->descent = CTFontGetDescent (ctfont) * PANGO_SCALE;

  metrics->underline_position = CTFontGetUnderlinePosition (ctfont) * PANGO_SCALE;
  metrics->underline_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE;

  metrics->strikethrough_position = metrics->ascent / 3;
  metrics->strikethrough_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE;

  layout = pango_layout_new (context);
  font_desc = pango_font_describe_with_absolute_size ((PangoFont *) font);
  pango_layout_set_font_description (layout, font_desc);
  pango_layout_set_text (layout, sample_str, -1);
  pango_layout_get_extents (layout, NULL, &extents);

  metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str);

  pango_layout_set_text (layout, "0123456789", -1);
  metrics->approximate_digit_width = max_glyph_width (layout);

  pango_font_description_free (font_desc);
  g_object_unref (layout);

  return metrics;
}
Beispiel #6
0
static void
gtk_font_chooser_default_init (GtkFontChooserInterface *iface)
{
  /**
   * GtkFontChooser:font:
   *
   * The font description as a string, e.g. "Sans Italic 12".
   */
  g_object_interface_install_property
     (iface,
      g_param_spec_string ("font",
                          P_("Font"),
                           P_("Font description as a string, e.g. \"Sans Italic 12\""),
                           GTK_FONT_CHOOSER_DEFAULT_FONT_NAME,
                           GTK_PARAM_READWRITE));

  /**
   * GtkFontChooser:font-desc:
   *
   * The font description as a #PangoFontDescription.
   */
  g_object_interface_install_property
     (iface,
      g_param_spec_boxed ("font-desc",
                          P_("Font description"),
                          P_("Font description as a PangoFontDescription struct"),
                          PANGO_TYPE_FONT_DESCRIPTION,
                          GTK_PARAM_READWRITE));

  /**
   * GtkFontChooser:preview-text:
   *
   * The string with which to preview the font.
   */
  g_object_interface_install_property
     (iface,
      g_param_spec_string ("preview-text",
                          P_("Preview text"),
                          P_("The text to display in order to demonstrate the selected font"),
                          pango_language_get_sample_string (NULL),
                          GTK_PARAM_READWRITE));

  /**
   * GtkFontChooser:show-preview-entry:
   *
   * Whether to show an entry to change the preview text.
   */
  g_object_interface_install_property
     (iface,
      g_param_spec_boolean ("show-preview-entry",
                          P_("Show preview text entry"),
                          P_("Whether the preview text entry is shown or not"),
                          TRUE,
                          GTK_PARAM_READWRITE));

  /**
   * GtkFontChooser::font-activated:
   * @self: the object which received the signal
   * @fontname: the font name
   *
   * Emitted when a font is activated.
   * This usually happens when the user double clicks an item,
   * or an item is selected and the user presses one of the keys
   * Space, Shift+Space, Return or Enter.
    */
  chooser_signals[SIGNAL_FONT_ACTIVATED] =
    g_signal_new ("font-activated",
                  GTK_TYPE_FONT_CHOOSER,
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GtkFontChooserIface, font_activated),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE,
                  1, G_TYPE_STRING);
}
static GdkPixmap *
create_text_pixmap(GtkWidget *drawing_area, FT_Face face)
{
    gint i, pixmap_width, pixmap_height, pos_y, textlen;
    GdkPixmap *pixmap = NULL;
    const gchar *text;
    Display *xdisplay;
    Drawable xdrawable;
    Visual *xvisual;
    Colormap xcolormap;
    XftDraw *draw;
    XftColor colour;
    XGlyphInfo extents;
    XftFont *font;
    gint *sizes = NULL, n_sizes, alpha_size;
    FcCharSet *charset = NULL;
    cairo_t *cr;
    GdkWindow *window = gtk_widget_get_window (drawing_area);

    text = pango_language_get_sample_string(NULL);
    if (! check_font_contain_text (face, text))
	{
	    pango_language_get_sample_string (pango_language_from_string ("en_US"));
	}

    textlen = strlen(text);

    /* create the XftDraw */
    xdisplay = GDK_PIXMAP_XDISPLAY(window);

	#if GTK_CHECK_VERSION(3, 0, 0)
		xvisual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window));
	#else
		xvisual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(window));
	#endif

    xcolormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(window));
    XftColorAllocName(xdisplay, xvisual, xcolormap, "black", &colour);

    /* work out what sizes to render */
    if (FT_IS_SCALABLE(face)) {
	n_sizes = 8;
	sizes = g_new(gint, n_sizes);
	sizes[0] = 8;
	sizes[1] = 10;
	sizes[2] = 12;
	sizes[3] = 18;
	sizes[4] = 24;
	sizes[5] = 36;
	sizes[6] = 48;
	sizes[7] = 72;
	alpha_size = 24;
    } else {
	/* use fixed sizes */
	n_sizes = face->num_fixed_sizes;
	sizes = g_new(gint, n_sizes);
	alpha_size = 0;
	for (i = 0; i < face->num_fixed_sizes; i++) {
	    sizes[i] = face->available_sizes[i].height;

	    /* work out which font size to render */
	    if (face->available_sizes[i].height <= 24)
		alpha_size = face->available_sizes[i].height;
	}
    }

    /* calculate size of pixmap to use (with 4 pixels padding) ... */
    pixmap_width = 8;
    pixmap_height = 8;

    font = get_font(xdisplay, face, alpha_size, charset);
    charset = FcCharSetCopy (font->charset);
    XftTextExtentsUtf8(xdisplay, font,
		       (guchar *)lowercase_text, strlen(lowercase_text), &extents);
    pixmap_height += extents.height + 4;
    pixmap_width = MAX(pixmap_width, 8 + extents.width);
    XftTextExtentsUtf8(xdisplay, font,
		       (guchar *)uppercase_text, strlen(uppercase_text), &extents);
    pixmap_height += extents.height + 4;
    pixmap_width = MAX(pixmap_width, 8 + extents.width);
    XftTextExtentsUtf8(xdisplay, font,
		       (guchar *)punctuation_text, strlen(punctuation_text), &extents);
    pixmap_height += extents.height + 4;
    pixmap_width = MAX(pixmap_width, 8 + extents.width);
    XftFontClose(xdisplay, font);

    pixmap_height += 8;

    for (i = 0; i < n_sizes; i++) {
	font = get_font(xdisplay, face, sizes[i], charset);
	if (!font) continue;
	XftTextExtentsUtf8(xdisplay, font, (guchar *)text, textlen, &extents);
	pixmap_height += extents.height + 4;
	pixmap_width = MAX(pixmap_width, 8 + extents.width);
	XftFontClose(xdisplay, font);
    }

    /* create pixmap */
    gtk_widget_set_size_request(drawing_area, pixmap_width, pixmap_height);
    pixmap = gdk_pixmap_new(window,
			    pixmap_width, pixmap_height, -1);
    if (!pixmap)
	goto end;
    cr = gdk_cairo_create (pixmap);
    cairo_set_source_rgb (cr, 1, 1, 1);
    cairo_paint (cr);
    cairo_destroy (cr);

    xdrawable = GDK_DRAWABLE_XID(pixmap);
    draw = XftDrawCreate(xdisplay, xdrawable, xvisual, xcolormap);

    /* draw text */
    pos_y = 4;
    font = get_font(xdisplay, face, alpha_size, charset);
    draw_string(xdisplay, draw, font, &colour, lowercase_text, &pos_y);
    draw_string(xdisplay, draw, font, &colour, uppercase_text, &pos_y);
    draw_string(xdisplay, draw, font, &colour, punctuation_text, &pos_y);
    XftFontClose(xdisplay, font);

    pos_y += 8;
    for (i = 0; i < n_sizes; i++) {
	font = get_font(xdisplay, face, sizes[i], charset);
	if (!font) continue;
	draw_string(xdisplay, draw, font, &colour, text, &pos_y);
	XftFontClose(xdisplay, font);
    }

    g_signal_connect(drawing_area, "expose-event", G_CALLBACK(expose_event),
                     pixmap);

 end:
    g_free(sizes);
    FcCharSetDestroy (charset);
    return pixmap;
}
PangoFontMetrics *
_pango_cairo_font_get_metrics (PangoFont     *font,
			       PangoLanguage *language)
{
  PangoCairoFont *cfont = (PangoCairoFont *) font;
  PangoCairoFontPrivate *cf_priv = PANGO_CAIRO_FONT_PRIVATE (font);
  PangoCairoFontMetricsInfo *info = NULL; /* Quiet gcc */
  GSList *tmp_list;

  const char *sample_str = pango_language_get_sample_string (language);

  tmp_list = cf_priv->metrics_by_lang;
  while (tmp_list)
    {
      info = tmp_list->data;

      if (info->sample_str == sample_str)    /* We _don't_ need strcmp */
	break;

      tmp_list = tmp_list->next;
    }

  if (!tmp_list)
    {
      PangoFontMap *fontmap;
      PangoContext *context;
      cairo_font_options_t *font_options;
      int height, shift;

      /* XXX this is racy.  need a ref'ing getter... */
      fontmap = pango_font_get_font_map (font);
      if (!fontmap)
        return pango_font_metrics_new ();
      fontmap = g_object_ref (fontmap);

      info = g_slice_new0 (PangoCairoFontMetricsInfo);

      cf_priv->metrics_by_lang = g_slist_prepend (cf_priv->metrics_by_lang, info);

      info->sample_str = sample_str;

      context = pango_font_map_create_context (fontmap);
      pango_context_set_language (context, language);
      font_options = cairo_font_options_create ();
      cairo_scaled_font_get_font_options (_pango_cairo_font_private_get_scaled_font (cf_priv), font_options);
      pango_cairo_context_set_font_options (context, font_options);
      cairo_font_options_destroy (font_options);

      info->metrics = (* PANGO_CAIRO_FONT_GET_IFACE (font)->create_metrics_for_context) (cfont, context);

      /* We may actually reuse ascent/descent we got from cairo here.  that's
       * in cf_priv->font_extents.
       */
      height = info->metrics->ascent + info->metrics->descent;
      switch (cf_priv->gravity)
	{
	  default:
	  case PANGO_GRAVITY_AUTO:
	  case PANGO_GRAVITY_SOUTH:
	    break;
	  case PANGO_GRAVITY_NORTH:
	    info->metrics->ascent = info->metrics->descent;
	    break;
	  case PANGO_GRAVITY_EAST:
	  case PANGO_GRAVITY_WEST:
	    {
	      int ascent = height / 2;
	      if (cf_priv->is_hinted)
	        ascent = PANGO_UNITS_ROUND (ascent);
	      info->metrics->ascent = ascent;
	    }
	}
      shift = (height - info->metrics->ascent) - info->metrics->descent;
      info->metrics->descent += shift;
      info->metrics->underline_position -= shift;
      info->metrics->strikethrough_position -= shift;
      info->metrics->ascent = height - info->metrics->descent;

      g_object_unref (context);
      g_object_unref (fontmap);
    }

  return pango_font_metrics_ref (info->metrics);
}
PangoFontMetrics *
_pango_cairo_font_get_metrics (PangoFont     *font,
			       PangoLanguage *language)
{
  PangoCairoFont *cfont = (PangoCairoFont *) font;
  PangoCairoFontPrivate *cf_priv = PANGO_CAIRO_FONT_PRIVATE (font);
  PangoCairoFontMetricsInfo *info = NULL; /* Quiet gcc */
  GSList *tmp_list;

  const char *sample_str = pango_language_get_sample_string (language);

  tmp_list = cf_priv->metrics_by_lang;
  while (tmp_list)
    {
      info = tmp_list->data;

      if (info->sample_str == sample_str)    /* We _don't_ need strcmp */
	break;

      tmp_list = tmp_list->next;
    }

  if (!tmp_list)
    {
      PangoFontMap *fontmap;
      PangoContext *context;
      cairo_font_options_t *font_options;
      PangoLayout *layout;
      PangoRectangle extents;
      PangoFontDescription *desc;
      cairo_scaled_font_t *scaled_font;
      cairo_matrix_t cairo_matrix;
      PangoMatrix pango_matrix;
      PangoMatrix identity = PANGO_MATRIX_INIT;

      int height, shift;

      /* XXX this is racy.  need a ref'ing getter... */
      fontmap = pango_font_get_font_map (font);
      if (!fontmap)
        return pango_font_metrics_new ();
      fontmap = g_object_ref (fontmap);

      info = g_slice_new0 (PangoCairoFontMetricsInfo);

      cf_priv->metrics_by_lang = g_slist_prepend (cf_priv->metrics_by_lang, info);

      info->sample_str = sample_str;

      scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv);

      context = pango_font_map_create_context (fontmap);
      pango_context_set_language (context, language);

      font_options = cairo_font_options_create ();
      cairo_scaled_font_get_font_options (scaled_font, font_options);
      pango_cairo_context_set_font_options (context, font_options);
      cairo_font_options_destroy (font_options);

      info->metrics = (* PANGO_CAIRO_FONT_GET_IFACE (font)->create_base_metrics_for_context) (cfont, context);

      /* We now need to adjust the base metrics for ctm */
      cairo_scaled_font_get_ctm (scaled_font, &cairo_matrix);
      pango_matrix.xx = cairo_matrix.xx;
      pango_matrix.yx = cairo_matrix.yx;
      pango_matrix.xy = cairo_matrix.xy;
      pango_matrix.yy = cairo_matrix.yy;
      pango_matrix.x0 = 0;
      pango_matrix.y0 = 0;
      if (G_UNLIKELY (0 != memcmp (&identity, &pango_matrix, 4 * sizeof (double))))
        {
	  double xscale = pango_matrix_get_font_scale_factor (&pango_matrix);
	  if (xscale) xscale = 1 / xscale;

	  info->metrics->ascent *= xscale;
	  info->metrics->descent *= xscale;
	  info->metrics->underline_position *= xscale;
	  info->metrics->underline_thickness *= xscale;
	  info->metrics->strikethrough_position *= xscale;
	  info->metrics->strikethrough_thickness *= xscale;
	}


      /* Set the matrix on the context so we don't have to adjust the derived
       * metrics. */
      pango_context_set_matrix (context, &pango_matrix);

      /* Update approximate_*_width now */
      layout = pango_layout_new (context);
      desc = pango_font_describe_with_absolute_size (font);
      pango_layout_set_font_description (layout, desc);
      pango_font_description_free (desc);

      pango_layout_set_text (layout, sample_str, -1);
      pango_layout_get_extents (layout, NULL, &extents);

      info->metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str);

      pango_layout_set_text (layout, "0123456789", -1);
      info->metrics->approximate_digit_width = max_glyph_width (layout);

      g_object_unref (layout);


      /* We may actually reuse ascent/descent we got from cairo here.  that's
       * in cf_priv->font_extents.
       */
      height = info->metrics->ascent + info->metrics->descent;
      switch (cf_priv->gravity)
	{
	  default:
	  case PANGO_GRAVITY_AUTO:
	  case PANGO_GRAVITY_SOUTH:
	    break;
	  case PANGO_GRAVITY_NORTH:
	    info->metrics->ascent = info->metrics->descent;
	    break;
	  case PANGO_GRAVITY_EAST:
	  case PANGO_GRAVITY_WEST:
	    {
	      int ascent = height / 2;
	      if (cf_priv->is_hinted)
	        ascent = PANGO_UNITS_ROUND (ascent);
	      info->metrics->ascent = ascent;
	    }
	}
      shift = (height - info->metrics->ascent) - info->metrics->descent;
      info->metrics->descent += shift;
      info->metrics->underline_position -= shift;
      info->metrics->strikethrough_position -= shift;
      info->metrics->ascent = height - info->metrics->descent;

      g_object_unref (context);
      g_object_unref (fontmap);
    }

  return pango_font_metrics_ref (info->metrics);
}