mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-08-25 02:36:07 +00:00
Add text layout functions copied from libgnomeui/gnome-icon-text.[ch] and
* libnautilus-extensions/nautilus-scalable-font.c: (text_layout_free_row), (nautilus_text_layout_free), (nautilus_text_layout_new), (nautilus_text_layout_paint): * libnautilus-extensions/nautilus-scalable-font.h: Add text layout functions copied from libgnomeui/gnome-icon-text.[ch] and modified to work with NautilusScalalbleFont and GdkPixbuf instead of GdkFont and GdkDrawable. * test/test-nautilus-font.c: (main): Add text layout test.
This commit is contained in:
parent
e38dfd4fc3
commit
4c7dc0ab85
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2000-09-07 Ramiro Estrugo <ramiro@eazel.com>
|
||||
|
||||
* libnautilus-extensions/nautilus-scalable-font.c:
|
||||
(text_layout_free_row), (nautilus_text_layout_free),
|
||||
(nautilus_text_layout_new), (nautilus_text_layout_paint):
|
||||
* libnautilus-extensions/nautilus-scalable-font.h:
|
||||
Add text layout functions copied from
|
||||
libgnomeui/gnome-icon-text.[ch] and modified to work with
|
||||
NautilusScalalbleFont and GdkPixbuf instead of GdkFont and
|
||||
GdkDrawable.
|
||||
|
||||
* test/test-nautilus-font.c: (main):
|
||||
Add text layout test.
|
||||
|
||||
2000-09-07 Ramiro Estrugo <ramiro@eazel.com>
|
||||
|
||||
* libnautilus-extensions/nautilus-icon-factory.c: (embed_text):
|
||||
|
|
|
@ -1327,6 +1327,308 @@ initialize_global_stuff_if_needed (void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The following text_layout stuff was shamelessly plundered
|
||||
* from libgnomeui/gnome-icon-text.[ch] by Federico Mena.
|
||||
*
|
||||
* It was hacked to use NautilusScalableFont and GdkPixbuf
|
||||
* instead of GdkFont and GdkDrawable. We want to use the
|
||||
* same layout algorithm in Nautilus so that both the smooth
|
||||
* and not smooth text rendering cases have predictably
|
||||
* similar result.
|
||||
*
|
||||
* I also made some minor Nautilus-like style changes. -re
|
||||
*
|
||||
*/
|
||||
static void
|
||||
text_layout_free_row (gpointer data, gpointer user_data)
|
||||
{
|
||||
NautilusTextLayoutRow *row;
|
||||
|
||||
if (data) {
|
||||
row = data;
|
||||
g_free (row->text);
|
||||
g_free (row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_text_layout_free:
|
||||
* @ti: An icon text info structure.
|
||||
*
|
||||
* Frees a &NautilusTextLayout structure. You should call this instead of
|
||||
* freeing the structure yourself.
|
||||
*/
|
||||
void
|
||||
nautilus_text_layout_free (NautilusTextLayout *text_info)
|
||||
{
|
||||
g_list_foreach (text_info->rows, text_layout_free_row, NULL);
|
||||
g_list_free (text_info->rows);
|
||||
g_free (text_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_text_layout_new:
|
||||
* @font: Name of the font that will be used to render the text.
|
||||
* @text: Text to be formatted.
|
||||
* @separators: Separators used for word wrapping, can be NULL.
|
||||
* @max_width: Width in pixels to be used for word wrapping.
|
||||
* @confine: Whether it is mandatory to wrap at @max_width.
|
||||
*
|
||||
* Creates a new &NautilusTextLayout structure by wrapping the specified
|
||||
* text. If non-NULL, the @separators argument defines a set of characters
|
||||
* to be used as word delimiters for performing word wrapping. If it is
|
||||
* NULL, then only spaces will be used as word delimiters.
|
||||
*
|
||||
* The @max_width argument is used to specify the width at which word
|
||||
* wrapping will be performed. If there is a very long word that does not
|
||||
* fit in a single line, the @confine argument can be used to specify
|
||||
* whether the word should be unconditionally split to fit or whether
|
||||
* the maximum width should be increased as necessary.
|
||||
*
|
||||
* Return value: A newly-created &NautilusTextLayout structure.
|
||||
*/
|
||||
NautilusTextLayout *
|
||||
nautilus_text_layout_new (const NautilusScalableFont *font,
|
||||
guint font_size,
|
||||
const char *text,
|
||||
const char *separators,
|
||||
int max_width,
|
||||
gboolean confine)
|
||||
{
|
||||
NautilusTextLayout *text_info;
|
||||
NautilusTextLayoutRow *row;
|
||||
const char *row_end;
|
||||
const char *s, *word_start, *word_end, *old_word_end;
|
||||
char *sub_text;
|
||||
int i, w_len, w;
|
||||
const char *text_iter;
|
||||
int text_len, separators_len;
|
||||
|
||||
g_return_val_if_fail (font != NULL, NULL);
|
||||
g_return_val_if_fail (font_size > 0, NULL);
|
||||
g_return_val_if_fail (text != NULL, NULL);
|
||||
g_return_val_if_fail (nautilus_strlen (text) > 0, NULL);
|
||||
|
||||
if (!separators)
|
||||
separators = " ";
|
||||
|
||||
text_len = strlen (text);
|
||||
|
||||
separators_len = strlen (separators);
|
||||
|
||||
text_info = g_new (NautilusTextLayout, 1);
|
||||
|
||||
text_info->rows = NULL;
|
||||
text_info->font = font;
|
||||
text_info->font_size = font_size;
|
||||
text_info->width = 0;
|
||||
text_info->height = 0;
|
||||
text_info->baseline_skip = font_size;
|
||||
|
||||
word_end = NULL;
|
||||
|
||||
text_iter = text;
|
||||
while (*text_iter) {
|
||||
for (row_end = text_iter; *row_end != 0 && *row_end != '\n'; row_end++);
|
||||
|
||||
/* Accumulate words from this row until they don't fit in the max_width */
|
||||
|
||||
s = text_iter;
|
||||
|
||||
while (s < row_end) {
|
||||
word_start = s;
|
||||
old_word_end = word_end;
|
||||
for (word_end = word_start; *word_end; word_end++) {
|
||||
const char *p;
|
||||
for (p = separators; *p; p++) {
|
||||
if (*word_end == *p)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found:
|
||||
if (word_end < row_end)
|
||||
word_end++;
|
||||
|
||||
if (nautilus_scalable_font_text_width (font, font_size, font_size, text_iter, word_end - text_iter) > max_width) {
|
||||
if (word_start == text_iter) {
|
||||
if (confine) {
|
||||
/* We must force-split the word. Look for a proper
|
||||
* place to do it.
|
||||
*/
|
||||
|
||||
w_len = word_end - word_start;
|
||||
|
||||
for (i = 1; i < w_len; i++) {
|
||||
w = nautilus_scalable_font_text_width (font, font_size, font_size, word_start, i);
|
||||
if (w > max_width) {
|
||||
if (i == 1)
|
||||
/* Shit, not even a single character fits */
|
||||
max_width = w;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create sub-row with the chars that fit */
|
||||
|
||||
sub_text = g_new (char, i);
|
||||
memcpy (sub_text, word_start, (i - 1) * sizeof (char));
|
||||
sub_text[i - 1] = 0;
|
||||
|
||||
row = g_new (NautilusTextLayoutRow, 1);
|
||||
row->text = sub_text;
|
||||
row->text_length = i - 1;
|
||||
row->width = nautilus_scalable_font_text_width (font, font_size, font_size,
|
||||
sub_text,
|
||||
strlen (sub_text));
|
||||
row->text = g_strdup (sub_text);
|
||||
if (row->text == NULL)
|
||||
row->text = g_strdup("");
|
||||
|
||||
text_info->rows = g_list_append (text_info->rows, row);
|
||||
|
||||
if (row->width > text_info->width)
|
||||
text_info->width = row->width;
|
||||
|
||||
text_info->height += text_info->baseline_skip;
|
||||
|
||||
/* Bump the text pointer */
|
||||
|
||||
text_iter += i - 1;
|
||||
s = text_iter;
|
||||
|
||||
continue;
|
||||
} else
|
||||
max_width = nautilus_scalable_font_text_width (font, font_size, font_size, word_start, word_end - word_start);
|
||||
|
||||
continue; /* Retry split */
|
||||
} else {
|
||||
word_end = old_word_end; /* Restore to region that does fit */
|
||||
break; /* Stop the loop because we found something that doesn't fit */
|
||||
}
|
||||
}
|
||||
|
||||
s = word_end;
|
||||
}
|
||||
|
||||
/* Append row */
|
||||
|
||||
if (text_iter == row_end) {
|
||||
/* We are on a newline, so append an empty row */
|
||||
|
||||
text_info->rows = g_list_append (text_info->rows, NULL);
|
||||
text_info->height += text_info->baseline_skip / 2;
|
||||
|
||||
/* Next! */
|
||||
|
||||
text_iter = row_end + 1;
|
||||
} else {
|
||||
/* Create subrow and append it to the list */
|
||||
|
||||
int sub_len;
|
||||
sub_len = word_end - text_iter;
|
||||
|
||||
sub_text = g_new (char, sub_len + 1);
|
||||
memcpy (sub_text, text_iter, sub_len * sizeof (char));
|
||||
sub_text[sub_len] = 0;
|
||||
|
||||
row = g_new (NautilusTextLayoutRow, 1);
|
||||
row->text = sub_text;
|
||||
row->text_length = sub_len;
|
||||
row->width = nautilus_scalable_font_text_width (font, font_size, font_size, sub_text, sub_len);
|
||||
row->text = g_strdup (sub_text);
|
||||
if (row->text == NULL)
|
||||
row->text = g_strdup("");
|
||||
|
||||
text_info->rows = g_list_append (text_info->rows, row);
|
||||
|
||||
if (row->width > text_info->width)
|
||||
text_info->width = row->width;
|
||||
|
||||
text_info->height += text_info->baseline_skip;
|
||||
|
||||
/* Next! */
|
||||
|
||||
text_iter = word_end;
|
||||
}
|
||||
}
|
||||
|
||||
return text_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_text_layout_paint:
|
||||
* @ti: An icon text info structure.
|
||||
* @drawable: Target drawable.
|
||||
* @gc: GC used to render the string.
|
||||
* @x: Left coordinate for text.
|
||||
* @y: Upper coordinate for text.
|
||||
* @just: Justification for text.
|
||||
*
|
||||
* Paints the formatted text in the icon text info structure onto a drawable.
|
||||
* This is just a sample implementation; applications can choose to use other
|
||||
* rendering functions.
|
||||
*/
|
||||
void
|
||||
nautilus_text_layout_paint (const NautilusTextLayout *text_info,
|
||||
GdkPixbuf *destination_pixbuf,
|
||||
int x,
|
||||
int y,
|
||||
GtkJustification just,
|
||||
guint32 color)
|
||||
{
|
||||
GList *item;
|
||||
const NautilusTextLayoutRow *row;
|
||||
int xpos;
|
||||
|
||||
g_return_if_fail (text_info != NULL);
|
||||
g_return_if_fail (destination_pixbuf != NULL);
|
||||
|
||||
/* y += text_info->font->ascent; */
|
||||
|
||||
for (item = text_info->rows; item; item = item->next) {
|
||||
if (item->data) {
|
||||
row = item->data;
|
||||
|
||||
switch (just) {
|
||||
case GTK_JUSTIFY_LEFT:
|
||||
xpos = 0;
|
||||
break;
|
||||
|
||||
case GTK_JUSTIFY_RIGHT:
|
||||
xpos = text_info->width - row->width;
|
||||
break;
|
||||
|
||||
case GTK_JUSTIFY_CENTER:
|
||||
xpos = (text_info->width - row->width) / 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Anyone care to implement GTK_JUSTIFY_FILL? */
|
||||
g_warning ("Justification type %d not supported. Using left-justification.",
|
||||
(int) just);
|
||||
xpos = 0;
|
||||
}
|
||||
|
||||
nautilus_scalable_font_draw_text (text_info->font,
|
||||
destination_pixbuf,
|
||||
x + xpos,
|
||||
y,
|
||||
NULL,
|
||||
text_info->font_size,
|
||||
text_info->font_size,
|
||||
row->text,
|
||||
row->text_length,
|
||||
color,
|
||||
255);
|
||||
|
||||
y += text_info->baseline_skip;
|
||||
} else
|
||||
y += text_info->baseline_skip / 2;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
|
||||
|
||||
void
|
||||
|
|
|
@ -155,6 +155,51 @@ gboolean nautilus_scalable_font_query_font (c
|
|||
NautilusStringList **slants,
|
||||
NautilusStringList **set_widths);
|
||||
|
||||
/*
|
||||
* The following text_layout stuff was shamelessly plundered
|
||||
* from libgnomeui/gnome-icon-text.[ch] by Federico Mena.
|
||||
*
|
||||
* It was hacked to use NautilusScalableFont and GdkPixbuf
|
||||
* instead of GdkFont and GdkDrawable. We want to use the
|
||||
* same layout algorithm in Nautilus so that both the smooth
|
||||
* and not smooth text rendering cases have predictably
|
||||
* similar result.
|
||||
*
|
||||
* I also made some minor Nautilus-like style changes. -re
|
||||
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *text;
|
||||
int width;
|
||||
int text_length;
|
||||
} NautilusTextLayoutRow;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GList *rows;
|
||||
const NautilusScalableFont *font;
|
||||
guint font_size;
|
||||
int width;
|
||||
int height;
|
||||
int baseline_skip;
|
||||
} NautilusTextLayout;
|
||||
|
||||
NautilusTextLayout *nautilus_text_layout_new (const NautilusScalableFont *font,
|
||||
guint font_size,
|
||||
const char *text,
|
||||
const char *separators,
|
||||
int max_width,
|
||||
gboolean confine);
|
||||
void nautilus_text_layout_paint (const NautilusTextLayout *text_info,
|
||||
GdkPixbuf *pixbuf,
|
||||
int x,
|
||||
int y,
|
||||
GtkJustification just,
|
||||
guint32 color);
|
||||
void nautilus_text_layout_free (NautilusTextLayout *text_info);
|
||||
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* NAUTILUS_SCALABLE_FONT_H */
|
||||
|
|
|
@ -1327,6 +1327,308 @@ initialize_global_stuff_if_needed (void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The following text_layout stuff was shamelessly plundered
|
||||
* from libgnomeui/gnome-icon-text.[ch] by Federico Mena.
|
||||
*
|
||||
* It was hacked to use NautilusScalableFont and GdkPixbuf
|
||||
* instead of GdkFont and GdkDrawable. We want to use the
|
||||
* same layout algorithm in Nautilus so that both the smooth
|
||||
* and not smooth text rendering cases have predictably
|
||||
* similar result.
|
||||
*
|
||||
* I also made some minor Nautilus-like style changes. -re
|
||||
*
|
||||
*/
|
||||
static void
|
||||
text_layout_free_row (gpointer data, gpointer user_data)
|
||||
{
|
||||
NautilusTextLayoutRow *row;
|
||||
|
||||
if (data) {
|
||||
row = data;
|
||||
g_free (row->text);
|
||||
g_free (row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_text_layout_free:
|
||||
* @ti: An icon text info structure.
|
||||
*
|
||||
* Frees a &NautilusTextLayout structure. You should call this instead of
|
||||
* freeing the structure yourself.
|
||||
*/
|
||||
void
|
||||
nautilus_text_layout_free (NautilusTextLayout *text_info)
|
||||
{
|
||||
g_list_foreach (text_info->rows, text_layout_free_row, NULL);
|
||||
g_list_free (text_info->rows);
|
||||
g_free (text_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_text_layout_new:
|
||||
* @font: Name of the font that will be used to render the text.
|
||||
* @text: Text to be formatted.
|
||||
* @separators: Separators used for word wrapping, can be NULL.
|
||||
* @max_width: Width in pixels to be used for word wrapping.
|
||||
* @confine: Whether it is mandatory to wrap at @max_width.
|
||||
*
|
||||
* Creates a new &NautilusTextLayout structure by wrapping the specified
|
||||
* text. If non-NULL, the @separators argument defines a set of characters
|
||||
* to be used as word delimiters for performing word wrapping. If it is
|
||||
* NULL, then only spaces will be used as word delimiters.
|
||||
*
|
||||
* The @max_width argument is used to specify the width at which word
|
||||
* wrapping will be performed. If there is a very long word that does not
|
||||
* fit in a single line, the @confine argument can be used to specify
|
||||
* whether the word should be unconditionally split to fit or whether
|
||||
* the maximum width should be increased as necessary.
|
||||
*
|
||||
* Return value: A newly-created &NautilusTextLayout structure.
|
||||
*/
|
||||
NautilusTextLayout *
|
||||
nautilus_text_layout_new (const NautilusScalableFont *font,
|
||||
guint font_size,
|
||||
const char *text,
|
||||
const char *separators,
|
||||
int max_width,
|
||||
gboolean confine)
|
||||
{
|
||||
NautilusTextLayout *text_info;
|
||||
NautilusTextLayoutRow *row;
|
||||
const char *row_end;
|
||||
const char *s, *word_start, *word_end, *old_word_end;
|
||||
char *sub_text;
|
||||
int i, w_len, w;
|
||||
const char *text_iter;
|
||||
int text_len, separators_len;
|
||||
|
||||
g_return_val_if_fail (font != NULL, NULL);
|
||||
g_return_val_if_fail (font_size > 0, NULL);
|
||||
g_return_val_if_fail (text != NULL, NULL);
|
||||
g_return_val_if_fail (nautilus_strlen (text) > 0, NULL);
|
||||
|
||||
if (!separators)
|
||||
separators = " ";
|
||||
|
||||
text_len = strlen (text);
|
||||
|
||||
separators_len = strlen (separators);
|
||||
|
||||
text_info = g_new (NautilusTextLayout, 1);
|
||||
|
||||
text_info->rows = NULL;
|
||||
text_info->font = font;
|
||||
text_info->font_size = font_size;
|
||||
text_info->width = 0;
|
||||
text_info->height = 0;
|
||||
text_info->baseline_skip = font_size;
|
||||
|
||||
word_end = NULL;
|
||||
|
||||
text_iter = text;
|
||||
while (*text_iter) {
|
||||
for (row_end = text_iter; *row_end != 0 && *row_end != '\n'; row_end++);
|
||||
|
||||
/* Accumulate words from this row until they don't fit in the max_width */
|
||||
|
||||
s = text_iter;
|
||||
|
||||
while (s < row_end) {
|
||||
word_start = s;
|
||||
old_word_end = word_end;
|
||||
for (word_end = word_start; *word_end; word_end++) {
|
||||
const char *p;
|
||||
for (p = separators; *p; p++) {
|
||||
if (*word_end == *p)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found:
|
||||
if (word_end < row_end)
|
||||
word_end++;
|
||||
|
||||
if (nautilus_scalable_font_text_width (font, font_size, font_size, text_iter, word_end - text_iter) > max_width) {
|
||||
if (word_start == text_iter) {
|
||||
if (confine) {
|
||||
/* We must force-split the word. Look for a proper
|
||||
* place to do it.
|
||||
*/
|
||||
|
||||
w_len = word_end - word_start;
|
||||
|
||||
for (i = 1; i < w_len; i++) {
|
||||
w = nautilus_scalable_font_text_width (font, font_size, font_size, word_start, i);
|
||||
if (w > max_width) {
|
||||
if (i == 1)
|
||||
/* Shit, not even a single character fits */
|
||||
max_width = w;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create sub-row with the chars that fit */
|
||||
|
||||
sub_text = g_new (char, i);
|
||||
memcpy (sub_text, word_start, (i - 1) * sizeof (char));
|
||||
sub_text[i - 1] = 0;
|
||||
|
||||
row = g_new (NautilusTextLayoutRow, 1);
|
||||
row->text = sub_text;
|
||||
row->text_length = i - 1;
|
||||
row->width = nautilus_scalable_font_text_width (font, font_size, font_size,
|
||||
sub_text,
|
||||
strlen (sub_text));
|
||||
row->text = g_strdup (sub_text);
|
||||
if (row->text == NULL)
|
||||
row->text = g_strdup("");
|
||||
|
||||
text_info->rows = g_list_append (text_info->rows, row);
|
||||
|
||||
if (row->width > text_info->width)
|
||||
text_info->width = row->width;
|
||||
|
||||
text_info->height += text_info->baseline_skip;
|
||||
|
||||
/* Bump the text pointer */
|
||||
|
||||
text_iter += i - 1;
|
||||
s = text_iter;
|
||||
|
||||
continue;
|
||||
} else
|
||||
max_width = nautilus_scalable_font_text_width (font, font_size, font_size, word_start, word_end - word_start);
|
||||
|
||||
continue; /* Retry split */
|
||||
} else {
|
||||
word_end = old_word_end; /* Restore to region that does fit */
|
||||
break; /* Stop the loop because we found something that doesn't fit */
|
||||
}
|
||||
}
|
||||
|
||||
s = word_end;
|
||||
}
|
||||
|
||||
/* Append row */
|
||||
|
||||
if (text_iter == row_end) {
|
||||
/* We are on a newline, so append an empty row */
|
||||
|
||||
text_info->rows = g_list_append (text_info->rows, NULL);
|
||||
text_info->height += text_info->baseline_skip / 2;
|
||||
|
||||
/* Next! */
|
||||
|
||||
text_iter = row_end + 1;
|
||||
} else {
|
||||
/* Create subrow and append it to the list */
|
||||
|
||||
int sub_len;
|
||||
sub_len = word_end - text_iter;
|
||||
|
||||
sub_text = g_new (char, sub_len + 1);
|
||||
memcpy (sub_text, text_iter, sub_len * sizeof (char));
|
||||
sub_text[sub_len] = 0;
|
||||
|
||||
row = g_new (NautilusTextLayoutRow, 1);
|
||||
row->text = sub_text;
|
||||
row->text_length = sub_len;
|
||||
row->width = nautilus_scalable_font_text_width (font, font_size, font_size, sub_text, sub_len);
|
||||
row->text = g_strdup (sub_text);
|
||||
if (row->text == NULL)
|
||||
row->text = g_strdup("");
|
||||
|
||||
text_info->rows = g_list_append (text_info->rows, row);
|
||||
|
||||
if (row->width > text_info->width)
|
||||
text_info->width = row->width;
|
||||
|
||||
text_info->height += text_info->baseline_skip;
|
||||
|
||||
/* Next! */
|
||||
|
||||
text_iter = word_end;
|
||||
}
|
||||
}
|
||||
|
||||
return text_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_text_layout_paint:
|
||||
* @ti: An icon text info structure.
|
||||
* @drawable: Target drawable.
|
||||
* @gc: GC used to render the string.
|
||||
* @x: Left coordinate for text.
|
||||
* @y: Upper coordinate for text.
|
||||
* @just: Justification for text.
|
||||
*
|
||||
* Paints the formatted text in the icon text info structure onto a drawable.
|
||||
* This is just a sample implementation; applications can choose to use other
|
||||
* rendering functions.
|
||||
*/
|
||||
void
|
||||
nautilus_text_layout_paint (const NautilusTextLayout *text_info,
|
||||
GdkPixbuf *destination_pixbuf,
|
||||
int x,
|
||||
int y,
|
||||
GtkJustification just,
|
||||
guint32 color)
|
||||
{
|
||||
GList *item;
|
||||
const NautilusTextLayoutRow *row;
|
||||
int xpos;
|
||||
|
||||
g_return_if_fail (text_info != NULL);
|
||||
g_return_if_fail (destination_pixbuf != NULL);
|
||||
|
||||
/* y += text_info->font->ascent; */
|
||||
|
||||
for (item = text_info->rows; item; item = item->next) {
|
||||
if (item->data) {
|
||||
row = item->data;
|
||||
|
||||
switch (just) {
|
||||
case GTK_JUSTIFY_LEFT:
|
||||
xpos = 0;
|
||||
break;
|
||||
|
||||
case GTK_JUSTIFY_RIGHT:
|
||||
xpos = text_info->width - row->width;
|
||||
break;
|
||||
|
||||
case GTK_JUSTIFY_CENTER:
|
||||
xpos = (text_info->width - row->width) / 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Anyone care to implement GTK_JUSTIFY_FILL? */
|
||||
g_warning ("Justification type %d not supported. Using left-justification.",
|
||||
(int) just);
|
||||
xpos = 0;
|
||||
}
|
||||
|
||||
nautilus_scalable_font_draw_text (text_info->font,
|
||||
destination_pixbuf,
|
||||
x + xpos,
|
||||
y,
|
||||
NULL,
|
||||
text_info->font_size,
|
||||
text_info->font_size,
|
||||
row->text,
|
||||
row->text_length,
|
||||
color,
|
||||
255);
|
||||
|
||||
y += text_info->baseline_skip;
|
||||
} else
|
||||
y += text_info->baseline_skip / 2;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
|
||||
|
||||
void
|
||||
|
|
|
@ -155,6 +155,51 @@ gboolean nautilus_scalable_font_query_font (c
|
|||
NautilusStringList **slants,
|
||||
NautilusStringList **set_widths);
|
||||
|
||||
/*
|
||||
* The following text_layout stuff was shamelessly plundered
|
||||
* from libgnomeui/gnome-icon-text.[ch] by Federico Mena.
|
||||
*
|
||||
* It was hacked to use NautilusScalableFont and GdkPixbuf
|
||||
* instead of GdkFont and GdkDrawable. We want to use the
|
||||
* same layout algorithm in Nautilus so that both the smooth
|
||||
* and not smooth text rendering cases have predictably
|
||||
* similar result.
|
||||
*
|
||||
* I also made some minor Nautilus-like style changes. -re
|
||||
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *text;
|
||||
int width;
|
||||
int text_length;
|
||||
} NautilusTextLayoutRow;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GList *rows;
|
||||
const NautilusScalableFont *font;
|
||||
guint font_size;
|
||||
int width;
|
||||
int height;
|
||||
int baseline_skip;
|
||||
} NautilusTextLayout;
|
||||
|
||||
NautilusTextLayout *nautilus_text_layout_new (const NautilusScalableFont *font,
|
||||
guint font_size,
|
||||
const char *text,
|
||||
const char *separators,
|
||||
int max_width,
|
||||
gboolean confine);
|
||||
void nautilus_text_layout_paint (const NautilusTextLayout *text_info,
|
||||
GdkPixbuf *pixbuf,
|
||||
int x,
|
||||
int y,
|
||||
GtkJustification just,
|
||||
guint32 color);
|
||||
void nautilus_text_layout_free (NautilusTextLayout *text_info);
|
||||
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* NAUTILUS_SCALABLE_FONT_H */
|
||||
|
|
|
@ -256,6 +256,64 @@ main (int argc, char* argv[])
|
|||
GREEN,
|
||||
255);
|
||||
|
||||
{
|
||||
NautilusTextLayout *text_info;
|
||||
const guint max_text_width = 100;
|
||||
const char *separators = " -_,;.?/&";
|
||||
const char *text = "This is a long piece of text!-This is the second piece-Now we have the third piece-And finally the fourth piece";
|
||||
const guint font_size = 14;
|
||||
ArtIRect layout_area;
|
||||
|
||||
text_info = nautilus_text_layout_new (font,
|
||||
font_size,
|
||||
text,
|
||||
separators,
|
||||
max_text_width,
|
||||
TRUE);
|
||||
g_assert (text_info != NULL);
|
||||
|
||||
layout_area.x0 = 20;
|
||||
layout_area.y0 = 550;
|
||||
layout_area.x1 = layout_area.x0 + max_text_width;
|
||||
layout_area.y1 = layout_area.y0 + 130;
|
||||
|
||||
draw_rectangle_around (pixbuf, &layout_area, RED);
|
||||
|
||||
nautilus_text_layout_paint (text_info,
|
||||
pixbuf,
|
||||
layout_area.x0,
|
||||
layout_area.y0,
|
||||
GTK_JUSTIFY_LEFT,
|
||||
BLACK);
|
||||
|
||||
layout_area.x0 += (max_text_width + 20);
|
||||
layout_area.x1 += (max_text_width + 20);
|
||||
|
||||
draw_rectangle_around (pixbuf, &layout_area, RED);
|
||||
|
||||
nautilus_text_layout_paint (text_info,
|
||||
pixbuf,
|
||||
layout_area.x0,
|
||||
layout_area.y0,
|
||||
GTK_JUSTIFY_CENTER,
|
||||
BLACK);
|
||||
|
||||
|
||||
layout_area.x0 += (max_text_width + 20);
|
||||
layout_area.x1 += (max_text_width + 20);
|
||||
|
||||
draw_rectangle_around (pixbuf, &layout_area, RED);
|
||||
|
||||
nautilus_text_layout_paint (text_info,
|
||||
pixbuf,
|
||||
layout_area.x0,
|
||||
layout_area.y0,
|
||||
GTK_JUSTIFY_RIGHT,
|
||||
BLACK);
|
||||
|
||||
nautilus_text_layout_free (text_info);
|
||||
}
|
||||
|
||||
nautilus_gdk_pixbuf_save_to_file (pixbuf, "font_test.png");
|
||||
|
||||
g_print ("saving test png file to font_test.png\n");
|
||||
|
@ -264,11 +322,3 @@ main (int argc, char* argv[])
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
icon_text_info = nautilus_icon_layout_text (details->smooth_font,
|
||||
details->smooth_font_size,
|
||||
text_piece, _(" -_,;.?/&"),
|
||||
max_text_width,
|
||||
TRUE);
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue