gtk_text vs. gtk_page

On Tue, 20 May 1997, Josh MacDonald wrote:

> As I've said in the past, text formatting like this isn't easy.
> Handling tabs is not a trivial matter, and was why I suggested
> people try and share code with the text widget.  
> You want tabs to work when you see:
> 	this text follows a tab.
> blah	so does this, and it's aligned with the above despite the
> 	word "blah" preceding the tab.

Actually, for Netscape-style HTML formatting, you don't ever need tabs 
with proportional fonts - you can always do the expansion into spaces 
before passing the text to the text widget.

> I worked on the text widget few days ago and discovered why everyone 
> had come to the conclusion that it totally didn't work.  The last 
> version I gave Pete, as I said, worked (with a few things I knew
> didn't work, but at least it didn't core dump).  Pete saw fit to
> make a quick change without testing it between my last version 
> which totally broke things.  I'll mail a version out sometime in 
> the next few weeks that works.  In the interest of form over function,
> the modifications I recently made were to disable all editing (because
> Pete broke it) and make it support background pixmaps which scroll 
> with the text (this is, of course, far more important than editing,
> right?).
> People working on a HTML browser without consulting the text widget
> are throwing away nearly 3500 lines devoted to text formatting, 
> drawing, and exposure.  It'll probably grow another 1500 by the
> time I finish h-scrolling and selection.  It's well laid out.  I figure
> it wouldn't be very difficult even, to allow images or child widgets
> to be inserted in the text.  The only hard part about an HTML widget
> from my perspective, using the text widget as a base, is handling
> aligned images (a more general description would be, handling "flows"
> in the FrameMaker sense). The text widget assumes there are lines of
> text, where each element is a member of some font with known 
> dimensions.  Using this abstraction, you can make embedded widgets
> a special case--a unique element in a unique font with the correct
> dimensions.  The problem is that HTML doesn't always work this way,
> because you have images aside a column of text (or, more generally,
> two columns of text or any other "flow").  I haven't come up
> with the solution to this little complication, but I suspect there
> is one--I haven't thought about it much (because its not required
> by the text widget..  its required for a word processor or web browser).
> Throwing away all that code is not, in my opinion, very wise.  Not
> only is there a lot to do with simply drawing the text, there's a
> lot more to do with efficiently caching the results of the computation
> and being able to do reexposures and scrolling quickly.
> >From the looks of it, you're charging in without thinking too much
> about the design.  Doing so, you're likely to miss much more than
> tabs.  I'm not trying to insult you guys, I'm just urging you to 
> consider rethinking your approach before you get too commited.
> Design is critical.  I assure you there's a 10x difference in the
> complexity and line-count between a poorly and well-written web
> browser.  Don't start with the assumption that since the goal is
> to end up with something small you should use a small or incomplete
> design (what would Brooks say about how much time to spend designing?).

Ok, I sense that a gauntlet has been thrown here.

I agree that studying the gtk_text widget is essential for anyone trying
to build a Web browser. It would also be great if the gtk_text and
gtk_page widgets got unified, to avoid proliferation of widgets that do
similar things. However, at this point, I'm still not completely convinced
that's the way to go. 

Let's phrase the question in somewhat objective terms: would a unified 
gtk_text/gtk_page widget (a) have fewer lines of code and (b) have 
adequate features and performance for Web browsing? I'm not sure, but 
here are some thoughts.

First, the gtk_page widget, as currently implemented, has quite a few
features that the gtk_text widget, as currently implemented (at least in
my copy of the 0.99.9 sources) lacks. First and foremost is support for
embedded widgets. It also has support for real line wraps, indentation
(sensitive to both line and paragraph breaks), variable amounts of spacing
in both horizontal and vertical dimensions, a set_width method for
controlling the set width, and clickable links. Further, in combination
with scrolledwindows it implements horizontal scrolling. 

In the other direction (and I'll give the benefit of a doubt regarding
incompletely implemented features), gtk_text implements editing,
selection, and a scrollable background pixmap. Selection is definitely
useful for a Web browser, but editing is of questionable value. I suppose 
the background pixmap is required for full Netscape HTML compliance, but 
it's pretty low on my feature list.

gtk_page is 1500 lines of code, gtk_text is 3500. I think one of the
reasons gtk_page is more concise is its choice of a simpler data structure
to represent the page. gtk_page uses an array of lines, each of which is
an array of words, while gtk_text uses a combination of a gapped text
buffer, a doubly linked list of text properties, and a line start cache.
I'm not claiming that the gtk_page design is better, just that it's 
completely appropriate for the goals of gzilla.

You mention throwing away code to do text formatting, drawing, and
exposure. I played with the gtk_text widget demo in testgtk, and found it
to be far from smooth. In particular, inserting characters caused the
entire widget to flash. The gtk_page widget does not have that problem. 
(currently, child widget resizes _do_ cause the widget to flash, but that
will be fixed by the next code escape). Thus, you're going to have to make
a stronger case that gtk_text's handling of these issues is superior to
gtk_page's. I'm willing to make the claim that the exposure processing of 
gtk_page is about as good as you can get.

Also, adding floating images would be pretty straightforward. Basically, 
you'd just add {left,right}_float_{width,height} fields to the GtkPageLine
data structure. The width fields have obvious meaning, and the height 
field specifies the height of the rectangle relative to the top of the 
line. Thus, the routines that maintain the invariants of the GtkPageLine 
data structure would subtract the line height from the previous height 
field, saturating at zero. Then, the routine that handles indentation and 
alignment would look at the height fields, and if non-zero, treat the 
width fields as extra indentation.

I'll make the case that such a change is particularly easy to do in 
gtk_page because the data structure is organized around the geometric 
layout of the page. gtk_text, on the other hand, is organized around the 
structure of the data. It's certainly possible to do everything that you 
can do in gtk_page, but it requires at least another level of 
indirection. Thus, I think there's a significant chance that adding all 
of gtk_page's features to gtk_text will cause the code to grow more than 
the size of gtk_page itself.

It may look like I'm jumping into the code of gzilla without having done 
my design homework, but that's simply not true. I did a Java-based chat 
server that had its own small Web browser in it. The Java display 
engine was the prototype for gtk_page. I also thought pretty seriously 
about how to implement all the text formatting I needed before committing 
to the design.

The one thing I did jump into head first was GTK+ programming. It's been 
pretty good, but I feel I've definitely come up against its limitations 
(many of which are in the size negotiation mechanism, which I think could 
use some serious work). My original plan was to support tables through 
the gtk_table mechanism, but now I think there's a good chance that this 
would stress GTK+'s poor size negotation well past the breaking point.

There is one serious misfeature in gtk_page: because it creates an X
window to hold the entire page, the size of the page is limited to the
maximum size of an X window: 32767 pixels. gtk_text doesn't have this
problem. However, I'm concerned about the aesthetics of scrolling when
such a widget has embedded widgets (with their own windows). What would
happen is that the page widget would do a pixmap-based scroll, which would
be fine. However, some of the data would scroll to under the child
widget's windows, and be lost. Then, (using size_allocate, I suppose), 
the child windows would be moved, causing expose events to go through the 
X server, for the areas that the child windows uncovered. These would 
then be handled by the page widget. As a consequence, the embedded 
widgets would appear to lag behind the text on the page, and also the 
text near widgets would flicker. This just wouldn't be cool.

I'm not sure what the best solution is. I'm still open to ideas.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]