Re: Word Underlining
- From: "Trever L. Adams" <tadams-lists myrealbox com>
- To: gtk-devel-list gnome org
- Subject: Re: Word Underlining
- Date: Thu, 23 Oct 2003 04:38:16 -0400
OK, I heard back from no one developers on this list but, I did hear
back from Damon Chaplin in regards to a similar email. He sent me an
older version of his patch ( to gtk-i18n Subject: Patch to add word
underlining on 21 Oct 2002 19:42:00 +0100). His patch had some
problems. It seems to me where so much is alike between
PANGO_ATTR_UNDERLINE_WORD and PANG_ATTR_UNDERLINE that it should be done
this way. I have reworked the Pango part of his patch (my original
work, nearly complete, is not available as I blew it away when I
realized Pango already had functionality used in this patch and didn't
need my silly hacks to handle parts of lines). I have included his
original GTK patch for someone else to look at. Basically, unless my
below query is answered by SIMPLIFY, any occurrence of checking for
_ATTR_UNDERLINE needs to also check for _ATTR_UNDERLINE_WORD
The only change I see as maybe necessary to my patch would be to set
PANGO_ATTR_UNDERLINE instead of _ATTR_UNDERLINE_WORD internally (much
how the _UNDERLINE_NONE is done) to allow simpler code paths elsewhere.
Is this desired?
Thank you for your consideration of my rework of Damon Chaplin's patch.
His understanding of how the various parts of Pango exceeded that of my
20 minutes of reading the code.
Other things I plan on doing (off a list he and I have):
o Displaying invisible chars, like spaces, tabs, paragraph terminators.
o Small caps for first n lines of paragraph.
o Kerning - customizable kerning for particular character pairs.
o Tracking - customizable for particular paragraphs.
o Runarounds & shaped text boxes - would need to cooperate with
higher-level code to determine where text can be placed on each line.
o Leading - locking to a baseline grid.
Small caps for first n lines might be something to work in the app and
not the library. The rest indeed seem to belong in the library. Any
complaints or objections? My next project will likely be the invisible
characters. After that, kerning. I see this as a program asking for an
override in specific cases, not telling the library to always do xyz
when seeing abc. After all, that is for the program to know.
Again, please carbon copy me as I can't handle much list volume at this
time.
Trever
On Wed, 2003-10-22 at 01:06, Trever L. Adams wrote:
> Currently, I see Pango has the ability to do underlines, but it doesn't
> break for white-spaces (namely spaces, though tabs seem to be in there
> as well). I am wanting to work on this to get this fixed. I see adding
> the following enums:
>
> PANGO_ATTR_UNDERLINE_WORD, /* PangoAttrInt - This doesn't underline
> whitespace */ to PangoAttrType;
>
> PANGO_UNDERLINE_SPECIAL /* This should underline with a squigly
> bit for spell checking, etc. */ to PangoUnderline;
>
> I am thinking of doing something like this:
>
> I plan on creating a structure similar to ink_rect that looks a bit like
> this:
>
> struct _PangoRectangleList
> {
> int x;
> int y;
> int width;
> int height;
> _PangoRectangleList *next
> };
>
> Or, it could just be a wrapper struct, whichever is preffered (i.e.
> struct PRList { _PangoRectangle PangoRectangle; _PangoRectangle *next};
>
*SNIP*
>
> Please, carbon copy me as I am not on the list and I really desire to
> know these answers.
>
> Also, is it too late to get these into 2.4 or whatever the next
> pango/gtk release will be?
>
> Thank you,
> Trever Adams
> --
> "One Woman can make you fly like an eagle Another can give you the
> strength of a lion But only One in the cycle of life can fill your heart
> with wonder And the wisdom that you have known a singular joy." --
> Unknown
--
"...the measure of a man is what he will do for another man, knowing he
will get nothing in return." -- Unknown
--- gtktextdisplay.c.orig Mon Oct 21 18:48:59 2002
+++ gtktextdisplay.c Mon Oct 21 18:48:09 2002
@@ -258,6 +258,7 @@
gint risen_y;
gint shaped_width_pixels = 0;
gboolean need_ink = FALSE;
+ PangoUnderline underline;
tmp_list = tmp_list->next;
@@ -281,8 +282,21 @@
fg_gc = render_state->fg_gc;
}
- if (appearance->underline != PANGO_UNDERLINE_NONE ||
- appearance->strikethrough)
+ /* If word-underlining is used, check if this is a non-word run, in
+ * which case we don't display the underline. (Pango will already have
+ * made sure the text is split into word and non-word runs.)
+ */
+ underline = appearance->underline;
+ if (underline == PANGO_UNDERLINE_WORD && run->item->num_chars)
+ {
+ const char *text = pango_layout_get_text (line->layout);
+ gunichar ch= g_utf8_get_char (text + run->item->offset);
+
+ if (!g_unichar_isgraph (ch))
+ underline = PANGO_UNDERLINE_NONE;
+ }
+
+ if (underline != PANGO_UNDERLINE_NONE || appearance->strikethrough)
need_ink = TRUE;
if (appearance->is_text)
@@ -434,7 +448,7 @@
g_assert_not_reached (); /* not a pixbuf or widget */
}
- switch (appearance->underline)
+ switch (underline)
{
case PANGO_UNDERLINE_NONE:
break;
@@ -447,6 +461,7 @@
risen_y + 3);
/* Fall through */
case PANGO_UNDERLINE_SINGLE:
+ case PANGO_UNDERLINE_WORD:
g_assert (need_ink);
gdk_draw_line (drawable, fg_gc,
x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
diff -ur pango-1.2.5.orig/pango/pango-attributes.c pango-1.2.5/pango/pango-attributes.c
--- pango-1.2.5.orig/pango/pango-attributes.c 2003-06-25 15:13:23.000000000 -0400
+++ pango-1.2.5/pango/pango-attributes.c 2003-10-23 04:23:10.885468774 -0400
@@ -555,7 +555,6 @@
return (PangoAttribute *)result;
}
-
/**
* pango_attr_underline_new:
* @underline: the underline style.
@@ -578,6 +577,27 @@
}
/**
+ * pango_attr_underline_word_new:
+ * @underline-word: the underline-word style.
+ *
+ * Create a new underline-word-style object.
+ *
+ * Return value: the new #PangoAttribute.
+ **/
+PangoAttribute *
+pango_attr_underline_word_new (PangoUnderline underline)
+{
+ static const PangoAttrClass klass = {
+ PANGO_ATTR_UNDERLINE_WORD,
+ pango_attr_int_copy,
+ pango_attr_int_destroy,
+ pango_attr_int_equal
+ };
+
+ return pango_attr_int_new (&klass, (int)underline);
+}
+
+/**
* pango_attr_strikethrough_new:
* @strikethrough: %TRUE if the text should be struck-through.
*
diff -ur pango-1.2.5.orig/pango/pango-attributes.h pango-1.2.5/pango/pango-attributes.h
--- pango-1.2.5.orig/pango/pango-attributes.h 2002-12-10 18:45:26.000000000 -0500
+++ pango-1.2.5/pango/pango-attributes.h 2003-10-23 04:23:50.098886313 -0400
@@ -80,7 +80,8 @@
PANGO_ATTR_STRIKETHROUGH, /* PangoAttrInt */
PANGO_ATTR_RISE, /* PangoAttrInt */
PANGO_ATTR_SHAPE, /* PangoAttrShape */
- PANGO_ATTR_SCALE /* PangoAttrFloat */
+ PANGO_ATTR_SCALE, /* PangoAttrFloat */
+ PANGO_ATTR_UNDERLINE_WORD /* PangoAttrInt */
} PangoAttrType;
typedef enum {
diff -ur pango-1.2.5.orig/pango/pango-context.c pango-1.2.5/pango/pango-context.c
--- pango-1.2.5.orig/pango/pango-context.c 2003-05-27 12:35:40.000000000 -0400
+++ pango-1.2.5/pango/pango-context.c 2003-10-23 03:59:55.000000000 -0400
@@ -385,6 +385,7 @@
const char *p;
const char *next;
GList *result = NULL;
+ gboolean word_underline_on = FALSE, last_was_word_char = FALSE;
PangoAnalysis *analyses;
@@ -435,10 +436,29 @@
{
PangoAnalysis *analysis = &analyses[i];
PangoAnalysis *last_analysis = i > 0 ? &analyses[i-1] : 0;
+ gboolean need_new_item = FALSE;
next = g_utf8_next_char (p);
- if (i == 0 ||
+ if (word_underline_on)
+ {
+ gboolean is_word_char;
+
+ /* Check if we've just switched from a word char to a non-word
+ * char, in which case we want to start a new run.
+ */
+ if (g_unichar_isgraph (g_utf8_get_char (p)))
+ is_word_char = TRUE;
+ else
+ is_word_char = FALSE;
+
+ if (is_word_char != last_was_word_char)
+ need_new_item = TRUE;
+
+ last_was_word_char = is_word_char;
+ }
+
+ if (i == 0 || need_new_item ||
text_ucs4[i] == '\t' || text_ucs4[i-1] == '\t' ||
embedding_levels[i] != embedding_levels[i-1] ||
analysis->shape_engine != last_analysis->shape_engine ||
@@ -447,6 +467,8 @@
analysis->language != last_analysis->language ||
analysis->extra_attrs != last_analysis->extra_attrs)
{
+ GSList *tmp_list;
+
/* assert that previous item got at least one char */
g_assert (item == NULL || item->length > 0);
g_assert (item == NULL || item->num_chars > 0);
@@ -478,6 +500,31 @@
else
item->analysis.extra_attrs = analysis->extra_attrs;
+ word_underline_on = FALSE;
+ for (tmp_list = item->analysis.extra_attrs; tmp_list;
+ tmp_list = tmp_list->next)
+ {
+ PangoAttribute *attr = tmp_list->data;
+
+ if (attr->klass->type == PANGO_ATTR_UNDERLINE_WORD)
+ {
+ /* Set the flag to indicate word underlining is on, so we
+ * look for word/non-word boundaries.
+ */
+ word_underline_on = TRUE;
+
+ if (g_unichar_isgraph (g_utf8_get_char (p)))
+ {
+ last_was_word_char = TRUE;
+ }
+ else
+ {
+ last_was_word_char = FALSE;
+ ((PangoAttrInt *)attr)->value = PANGO_UNDERLINE_NONE;
+ }
+ }
+ }
+
result = g_list_prepend (result, item);
}
else
diff -ur pango-1.2.5.orig/pango/pangoft2.c pango-1.2.5/pango/pangoft2.c
--- pango-1.2.5.orig/pango/pangoft2.c 2003-08-08 13:05:05.000000000 -0400
+++ pango-1.2.5/pango/pangoft2.c 2003-10-23 04:06:28.419740064 -0400
@@ -1009,6 +1009,7 @@
switch (attr->klass->type)
{
case PANGO_ATTR_UNDERLINE:
+ case PANGO_ATTR_UNDERLINE_WORD:
if (uline)
*uline = ((PangoAttrInt *)attr)->value;
break;
Only in pango-1.2.5.orig/pango: pangoft2.rc
diff -ur pango-1.2.5.orig/pango/pango-layout.c pango-1.2.5/pango/pango-layout.c
--- pango-1.2.5.orig/pango/pango-layout.c 2003-06-25 15:13:23.000000000 -0400
+++ pango-1.2.5/pango/pango-layout.c 2003-10-23 04:07:20.269012873 -0400
@@ -2873,7 +2873,8 @@
PANGO_ATTR_BACKGROUND,
PANGO_ATTR_UNDERLINE,
PANGO_ATTR_STRIKETHROUGH,
- PANGO_ATTR_RISE
+ PANGO_ATTR_RISE,
+ PANGO_ATTR_UNDERLINE_WORD
};
int i;
@@ -3882,6 +3883,7 @@
switch (attr->klass->type)
{
case PANGO_ATTR_UNDERLINE:
+ case PANGO_ATTR_UNDERLINE_WORD:
if (uline)
*uline = ((PangoAttrInt *)attr)->value;
break;
diff -ur pango-1.2.5.orig/pango/pangowin32.c pango-1.2.5/pango/pangowin32.c
--- pango-1.2.5.orig/pango/pangowin32.c 2003-08-08 13:05:05.000000000 -0400
+++ pango-1.2.5/pango/pangowin32.c 2003-10-23 04:07:51.814719433 -0400
@@ -909,6 +909,7 @@
switch (attr->klass->type)
{
case PANGO_ATTR_UNDERLINE:
+ case PANGO_ATTR_UNDERLINE_WORD:
if (uline)
*uline = ((PangoAttrInt *)attr)->value;
break;
diff -ur pango-1.2.5.orig/pango/pangox.c pango-1.2.5/pango/pangox.c
--- pango-1.2.5.orig/pango/pangox.c 2003-05-27 16:13:46.000000000 -0400
+++ pango-1.2.5/pango/pangox.c 2003-10-23 04:08:31.181113569 -0400
@@ -1732,6 +1732,7 @@
switch (attr->klass->type)
{
case PANGO_ATTR_UNDERLINE:
+ case PANGO_ATTR_UNDERLINE_WORD:
if (uline)
*uline = ((PangoAttrInt *)attr)->value;
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]