Andre Poenitz wrote: > On Tue, Oct 21, 2003 at 09:25:46AM +0000, Angus Leeming wrote: >> Andre Poenitz wrote: >> >> Is this just a wild flight of fancy, or does anybody else think >> >> that it's a sensible proposal? >> > >> > I think this could be handled on a case-by-case base by using >> > some helper functions in the insets that really need it. >> >> Actually, I did some reading and I think I have stumbled across >> something very powerful. >> >> The C++ streams allow us to define arbitrary new modifiers --- and >> enable subsequent operations on the stream to be aware of them. For >> example, the code below would be used >> std::ostringstream os; >> os << font::setFamily(font::SERIF) << "Andr? " >> << font::setFamily(font::SANS_SERIF) << "P?nitz\n"; > > I know this in theory but never managed to work with that in praxi. > > I wanted to transform the different "math output stream" to a scheme > like that at one point of time but then got distracted somehow... > >> Note that it works on existing stream types!!! Thereafter one would >> need to write a 'decipherer'. For example, something to establish >> the width of the string in this font, or to paint it, but the >> beauty is that this 'mark-up' is entirely separate. > > Not really, is it? > > You just modify some state of the stream (i.e. to "SERIF"). Than > every write on that stream has to check this state and respond to > it. > > It is not a kind of out-of-band signalling, rather some fancy way to > add more data room to a stream. > > This safes you writing lots of 'operator<<' for the standard types > like int, double, ... fro your custom streams, but that's it.
> And now you've got some new state in the stream object. It does not > affect the data buffer at all. This is basically only syntactic > sugar over > > void write(ostream & os, MyObject const &, SomeExtraData const & > extra) > > by combining 'os' and 'extra' and re-using operator<<() for the base > types. My main point is that the metrics and draw routines repeat large blocks of code and that my separating the information from the way it is used we can only win. I agree that we need to operate on the resulting data and I openly admit that I haven't read enough to do that. Perhaps you can help fill in my knowledge gap? I imagine something like int fontWidth(std::ostream & os) { int width = 0; std::ostream::iterator it = os.begin(); std::ostream::iterator end = os.end(); for (; it != end; ++it) { int const family = os.iword(setFamily::getAlloc()) if (family == -1) { std::cout << "Family data not set\n"; continue; } LyXFont font(family); width += (*it, font); } return width; } But such a stream would also allow the frontends to implement their own mark-up. Ie, pass a stringstream to the dialog and get bold and italic mark up in the right places. Regards, Angus