summaryrefslogtreecommitdiff
path: root/libnautilus-private/nautilus-scalable-font.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnautilus-private/nautilus-scalable-font.c')
-rw-r--r--libnautilus-private/nautilus-scalable-font.c486
1 files changed, 356 insertions, 130 deletions
diff --git a/libnautilus-private/nautilus-scalable-font.c b/libnautilus-private/nautilus-scalable-font.c
index 8b51af0b8..d4d3ed49a 100644
--- a/libnautilus-private/nautilus-scalable-font.c
+++ b/libnautilus-private/nautilus-scalable-font.c
@@ -606,6 +606,7 @@ nautilus_scalable_font_measure_text (const NautilusScalableFont *font,
guint font_width,
guint font_height,
const char *text,
+ guint text_length,
guint *text_width_out,
guint *text_height_out)
{
@@ -622,10 +623,12 @@ nautilus_scalable_font_measure_text (const NautilusScalableFont *font,
*text_width_out = 0;
*text_height_out = 0;
- if (text == NULL) {
+ if (text == NULL || text[0] == '\0' || text_length == 0) {
return;
}
+ g_return_if_fail (text_length <= strlen (text));
+
art_affine_identity (affine);
/* FIXME bugzilla.eazel.com 2544: We need to change rsvg_ft_render_string() to accept
@@ -635,6 +638,7 @@ nautilus_scalable_font_measure_text (const NautilusScalableFont *font,
glyph = rsvg_ft_render_string (global_rsvg_ft_context,
font->detail->font_handle,
text,
+ text_length,
font_width,
font_height,
affine,
@@ -647,107 +651,13 @@ nautilus_scalable_font_measure_text (const NautilusScalableFont *font,
}
void
-nautilus_scalable_font_measure_text_lines (NautilusScalableFont *font,
- guint font_width,
- guint font_height,
- const char *text_lines[],
- guint num_text_lines,
- guint text_line_widths[],
- guint text_line_heights[],
- guint *max_width_out,
- guint *total_height_out)
-{
- guint i;
-
- g_return_if_fail (NAUTILUS_IS_SCALABLE_FONT (font));
- g_return_if_fail (font_width > 0);
- g_return_if_fail (font_height > 0);
- g_return_if_fail (text_lines != NULL);
- g_return_if_fail (text_line_widths != NULL);
- g_return_if_fail (text_line_heights != NULL);
- g_return_if_fail (num_text_lines > 0);
-
- if (max_width_out != NULL) {
- *max_width_out = 0;
- }
-
- if (total_height_out != NULL) {
- *total_height_out = 0;
- }
-
- for (i = 0; i < num_text_lines; i++) {
- g_assert (text_lines[i] != NULL);
-
- nautilus_scalable_font_measure_text (font,
- font_width,
- font_height,
- text_lines[i],
- &text_line_widths[i],
- &text_line_heights[i]);
-
- if (total_height_out != NULL) {
- *total_height_out += text_line_heights[i];
- }
-
- if ((max_width_out != NULL) && (text_line_widths[i] > *max_width_out)) {
- *max_width_out = text_line_widths[i];
- }
- }
-}
-
-guint
-nautilus_scalable_font_largest_fitting_font_size (const NautilusScalableFont *font,
- const char *text,
- guint available_width,
- const guint font_sizes[],
- guint num_font_sizes)
-{
- NautilusStringList *tokenized_string;
- guint i;
- char *longest_string;
-
- g_return_val_if_fail (NAUTILUS_IS_SCALABLE_FONT (font), 0);
- g_return_val_if_fail (font_sizes != NULL, 0);
- g_return_val_if_fail (num_font_sizes > 0, 0);
-
- if (text == NULL || text[0] == '\0' || available_width < 1) {
- return font_sizes[num_font_sizes - 1];
- }
-
- tokenized_string = nautilus_string_list_new_from_tokens (text, "\n", FALSE);
- longest_string = nautilus_string_list_get_longest_string (tokenized_string);
- g_assert (longest_string != NULL);
- nautilus_string_list_free (tokenized_string);
-
- for (i = 0; i < num_font_sizes; i++) {
- guint text_width;
- guint text_height;
-
- nautilus_scalable_font_measure_text (font,
- font_sizes[i],
- font_sizes[i],
- longest_string,
- &text_width,
- &text_height);
-
- if (text_width <= available_width) {
- g_free (longest_string);
- return font_sizes[i];
- }
- }
-
- g_free (longest_string);
-
- return font_sizes[num_font_sizes - 1];
-}
-
-void
nautilus_scalable_font_draw_text (const NautilusScalableFont *font,
GdkPixbuf *destination_pixbuf,
const ArtIRect *destination_area,
guint font_width,
guint font_height,
const char *text,
+ guint text_length,
guint32 color,
guchar overall_alpha)
{
@@ -774,15 +684,18 @@ nautilus_scalable_font_draw_text (const NautilusScalableFont *font,
g_return_if_fail (font_width > 0);
g_return_if_fail (font_height > 0);
- if (text == NULL) {
+ if (text == NULL || text[0] == '\0' || text_length == 0) {
return;
}
+ g_return_if_fail (text_length <= strlen (text));
+
art_affine_identity (affine);
glyph = rsvg_ft_render_string (global_rsvg_ft_context,
font->detail->font_handle,
text,
+ text_length,
font_width,
font_height,
affine,
@@ -837,6 +750,57 @@ nautilus_scalable_font_draw_text (const NautilusScalableFont *font,
rsvg_ft_glyph_unref (glyph);
}
+#if 0
+void
+nautilus_scalable_font_measure_text_lines (NautilusScalableFont *font,
+ guint font_width,
+ guint font_height,
+ const char *text_lines[],
+ guint num_text_lines,
+ guint text_line_widths[],
+ guint text_line_heights[],
+ guint *max_width_out,
+ guint *total_height_out)
+{
+ guint i;
+
+ g_return_if_fail (NAUTILUS_IS_SCALABLE_FONT (font));
+ g_return_if_fail (font_width > 0);
+ g_return_if_fail (font_height > 0);
+ g_return_if_fail (text_lines != NULL);
+ g_return_if_fail (text_line_widths != NULL);
+ g_return_if_fail (text_line_heights != NULL);
+ g_return_if_fail (num_text_lines > 0);
+
+ if (max_width_out != NULL) {
+ *max_width_out = 0;
+ }
+
+ if (total_height_out != NULL) {
+ *total_height_out = 0;
+ }
+
+ for (i = 0; i < num_text_lines; i++) {
+ g_assert (text_lines[i] != NULL);
+
+ nautilus_scalable_font_measure_text (font,
+ font_width,
+ font_height,
+ text_lines[i],
+ strlen (text_lines[i]),
+ &text_line_widths[i],
+ &text_line_heights[i]);
+
+ if (total_height_out != NULL) {
+ *total_height_out += text_line_heights[i];
+ }
+
+ if ((max_width_out != NULL) && (text_line_widths[i] > *max_width_out)) {
+ *max_width_out = text_line_widths[i];
+ }
+ }
+}
+
void
nautilus_scalable_font_draw_text_lines (const NautilusScalableFont *font,
GdkPixbuf *destination_pixbuf,
@@ -883,48 +847,310 @@ nautilus_scalable_font_draw_text_lines (const NautilusScalableFont *font,
ArtIRect area;
g_assert (text_lines[i] != NULL);
- g_assert (text_line_widths[i] > 0);
- g_assert (text_line_heights[i] > 0);
-
- switch (justification) {
- case GTK_JUSTIFY_LEFT:
- area.x0 = x;
- break;
-
- case GTK_JUSTIFY_CENTER:
- case GTK_JUSTIFY_FILL:
- if (text_line_widths[i] <= available_width) {
- area.x0 = x + ((available_width - text_line_widths[i]) / 2);
- }
- else {
- area.x0 = x - ((text_line_widths[i] - available_width) / 2);
+
+ if (text_line_widths[i] == 0 && text_line_heights[i] == 0) {
+ y += font_height;
+ }
+ else {
+ switch (justification) {
+ case GTK_JUSTIFY_LEFT:
+ area.x0 = x;
+ break;
+
+ case GTK_JUSTIFY_CENTER:
+ case GTK_JUSTIFY_FILL:
+ if (text_line_widths[i] <= available_width) {
+ area.x0 = x + ((available_width - text_line_widths[i]) / 2);
+ }
+ else {
+ area.x0 = x - ((text_line_widths[i] - available_width) / 2);
+ }
+ break;
+
+ case GTK_JUSTIFY_RIGHT:
+ area.x0 = x + available_width - text_line_widths[i];
+ break;
+
+ default:
+ g_assert_not_reached ();
}
- break;
+
+ area.x1 = area.x0 + text_line_widths[i];
+ area.y0 = y;
+ area.y1 = area.y0 + text_line_heights[i];
+
+ nautilus_scalable_font_draw_text (font,
+ destination_pixbuf,
+ &area,
+ font_width,
+ font_height,
+ text_lines[i],
+ strlen (text_lines[i]),
+ color,
+ overall_alpha);
+
+ y += (line_offset + text_line_heights[i]);
+ }
+ }
+}
+#else
+void
+nautilus_scalable_font_measure_text_lines (NautilusScalableFont *font,
+ guint font_width,
+ guint font_height,
+ const char *text,
+ guint num_text_lines,
+ guint text_line_widths[],
+ guint text_line_heights[],
+ guint *max_width_out,
+ guint *total_height_out)
+{
+ guint i;
+ const char *line;
+
+ g_return_if_fail (NAUTILUS_IS_SCALABLE_FONT (font));
+ g_return_if_fail (font_width > 0);
+ g_return_if_fail (font_height > 0);
+ g_return_if_fail (text != NULL);
+ g_return_if_fail (text_line_widths != NULL);
+ g_return_if_fail (text_line_heights != NULL);
+ g_return_if_fail (num_text_lines > 0);
+ g_return_if_fail (num_text_lines <= (nautilus_str_count_characters (text, '\n') + 1));
- case GTK_JUSTIFY_RIGHT:
- area.x0 = x + available_width - text_line_widths[i];
- break;
+ if (max_width_out != NULL) {
+ *max_width_out = 0;
+ }
- default:
- g_assert_not_reached ();
+ if (total_height_out != NULL) {
+ *total_height_out = 0;
+ }
+
+ line = text;
+
+ /*
+ * We can safely iterate for 'num_text_lines' since we already checked that the
+ * string does indeed contain as many lines.
+ */
+ for (i = 0; i < num_text_lines; i++) {
+ const char *next_new_line;
+ guint length;
+
+ g_assert (line != NULL);
+
+ /* Look for the next new line */
+ next_new_line = strchr (line, '\n');
+
+ if (next_new_line != NULL) {
+ length = (next_new_line - line);
+ }
+ else {
+ length = strlen (line);
+ }
+
+ /* Deal with empty lines */
+ if (length == 0) {
+ text_line_widths[i] = 0;
+ text_line_heights[i] = font_height;
+ }
+ else {
+ nautilus_scalable_font_measure_text (font,
+ font_width,
+ font_height,
+ line,
+ length,
+ &text_line_widths[i],
+ &text_line_heights[i]);
+ }
+
+ if (next_new_line != NULL) {
+ line = next_new_line + 1;
+ }
+ else {
+ line = NULL;
}
+
+ /* Keep track of total height */
+ if (total_height_out != NULL) {
+ *total_height_out += text_line_heights[i];
+ }
+
+ /* Keep track of max width */
+ if ((max_width_out != NULL) && (text_line_widths[i] > *max_width_out)) {
+ *max_width_out = text_line_widths[i];
+ }
+ }
+}
- area.x1 = area.x0 + text_line_widths[i];
- area.y0 = y;
- area.y1 = area.y0 + text_line_heights[i];
+void
+nautilus_scalable_font_draw_text_lines (const NautilusScalableFont *font,
+ GdkPixbuf *destination_pixbuf,
+ const ArtIRect *destination_area,
+ guint font_width,
+ guint font_height,
+ const char *text,
+ guint num_text_lines,
+ const guint text_line_widths[],
+ const guint text_line_heights[],
+ GtkJustification justification,
+ guint line_offset,
+ guint32 color,
+ guchar overall_alpha)
+{
+ guint i;
+ const char *line;
- nautilus_scalable_font_draw_text (font,
- destination_pixbuf,
- &area,
- font_width,
- font_height,
- text_lines[i],
- color,
- overall_alpha);
+ gint x;
+ gint y;
- y += (line_offset + text_line_heights[i]);
+ guint available_width;
+ guint available_height;
+
+ g_return_if_fail (NAUTILUS_IS_SCALABLE_FONT (font));
+ g_return_if_fail (destination_pixbuf != NULL);
+ g_return_if_fail (destination_area != NULL);
+ g_return_if_fail (font_width > 0);
+ g_return_if_fail (font_height > 0);
+ g_return_if_fail (text_line_widths != NULL);
+ g_return_if_fail (text_line_heights != NULL);
+ g_return_if_fail (justification >= GTK_JUSTIFY_LEFT && justification <= GTK_JUSTIFY_FILL);
+ g_return_if_fail (destination_area->x1 > destination_area->x0);
+ g_return_if_fail (destination_area->y1 > destination_area->y0);
+ g_return_if_fail (num_text_lines > 0);
+ g_return_if_fail (num_text_lines <= (nautilus_str_count_characters (text, '\n') + 1));
+
+ x = destination_area->x0;
+ y = destination_area->y0;
+
+ available_width = destination_area->x1 - destination_area->x0;
+ available_height = destination_area->y1 - destination_area->y0;
+
+ line = text;
+
+ /*
+ * We can safely iterate for 'num_text_lines' since we already checked that the
+ * string does indeed contain as many lines.
+ */
+ for (i = 0; i < num_text_lines; i++) {
+ const char *next_new_line;
+ guint length;
+
+ g_assert (line != NULL);
+
+ /* Look for the next new line */
+ next_new_line = strchr (line, '\n');
+
+ if (next_new_line != NULL) {
+ length = (next_new_line - line);
+ }
+ else {
+ length = strlen (line);
+ }
+
+ /* Deal with empty lines */
+ if (length == 0) {
+ y += font_height;
+ }
+ else {
+ ArtIRect area;
+
+ switch (justification) {
+ case GTK_JUSTIFY_LEFT:
+ area.x0 = x;
+ break;
+
+ case GTK_JUSTIFY_CENTER:
+ case GTK_JUSTIFY_FILL:
+ if (text_line_widths[i] <= available_width) {
+ area.x0 = x + ((available_width - text_line_widths[i]) / 2);
+ }
+ else {
+ area.x0 = x - ((text_line_widths[i] - available_width) / 2);
+ }
+ break;
+
+ case GTK_JUSTIFY_RIGHT:
+ area.x0 = x + available_width - text_line_widths[i];
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ area.x1 = area.x0 + text_line_widths[i];
+ area.y0 = y;
+ area.y1 = area.y0 + text_line_heights[i];
+
+ nautilus_scalable_font_draw_text (font,
+ destination_pixbuf,
+ &area,
+ font_width,
+ font_height,
+ line,
+ length,
+ color,
+ overall_alpha);
+
+ y += (line_offset + text_line_heights[i]);
+ }
+
+ if (next_new_line != NULL) {
+ line = next_new_line + 1;
+ }
+ else {
+ line = NULL;
+ }
}
}
+#endif
+
+guint
+nautilus_scalable_font_largest_fitting_font_size (const NautilusScalableFont *font,
+ const char *text,
+ guint available_width,
+ const guint font_sizes[],
+ guint num_font_sizes)
+{
+ NautilusStringList *tokenized_string;
+ guint i;
+ char *longest_string;
+ guint longest_string_length;
+
+ g_return_val_if_fail (NAUTILUS_IS_SCALABLE_FONT (font), 0);
+ g_return_val_if_fail (font_sizes != NULL, 0);
+ g_return_val_if_fail (num_font_sizes > 0, 0);
+
+ if (text == NULL || text[0] == '\0' || available_width < 1) {
+ return font_sizes[num_font_sizes - 1];
+ }
+
+ tokenized_string = nautilus_string_list_new_from_tokens (text, "\n", FALSE);
+ longest_string = nautilus_string_list_get_longest_string (tokenized_string);
+ g_assert (longest_string != NULL);
+ nautilus_string_list_free (tokenized_string);
+ longest_string_length = strlen (longest_string);
+
+ for (i = 0; i < num_font_sizes; i++) {
+ guint text_width;
+ guint text_height;
+
+ nautilus_scalable_font_measure_text (font,
+ font_sizes[i],
+ font_sizes[i],
+ longest_string,
+ longest_string_length,
+ &text_width,
+ &text_height);
+
+ if (text_width <= available_width) {
+ g_free (longest_string);
+ return font_sizes[i];
+ }
+ }
+
+ g_free (longest_string);
+
+ return font_sizes[num_font_sizes - 1];
+}
NautilusScalableFont *
nautilus_scalable_font_get_default_font (void)