On Mon, Aug 04, 2003 at 10:20:41AM +0100, Angus Leeming spake thusly: > > Martin Vermeer wrote: > > > On Fri, Aug 01, 2003 at 07:02:29AM +0300, Martin Vermeer spake > > thusly: > > > > ... > > > >> One remaining problem: the place where the colour is used in > >> insets/insetbranch.C where we have > >> > >> setBackgroundColor(lc.getFromGUIName(color)); > >> > >> 'color' being the string name. So, an LColor is being generated. > >> Can the colour picker handle that (i.e. add a legit LColor and name > >> to the database, where the above will find it) for an arbitrary RGB > >> triplet? I seem to remember this mentioned somewhere. > > > > Having analyzed this proble a little further, it looks pretty bad. > > The need by setBackgroundColor for an LColor can be traced back to > > fillRectangle in Painter and in XPainter, which calls XFillRectangle > > that takes a Graphics Context as argument... produced by (file > > ColorHandler.C) > > Well, take heart! I don't think it is too bad myself. > > The problem stems from the fact that 'class LColor' uses entries of > type 'enum LColor::color' to access the various functions. This > necessarily means that the number of colors is hardcoded at compile > time. Ultimately the data is stored in > std::map<LColor::color, information> infotab; > > Now, my suggestion to you is to change this store to > std::map<int, information> infotab; > and to ADD more accessor methods > string const getGUIName(string const & some_id) const; > string const getX11Name(string const & some_id) const; > string const getLaTeXName(string const & some_id) const; > > Internal to LColor.C you would have an additional > std::map(string, int) transform; > that mapped this string id to the identifier used in 'infotab'. > > Voilą! You are able to prescribe new colors dynamically.
OK, sounds like an interesting approach. (We'll still end up at 20x LOC of the original Branches implementation, don't you worry :-) But... setBackgroundColor still expects a LColor::color argument, not an integer (or an id string, which would be better in a way). Would I end up using something like a cast? e.g. static_cast<LColor::color>(lc.getIntFromGUIName(color) as the argument, with color the name of the branch? Not exactly elegant. > > Do I really have to start tinkering with this deep stuff, e.g., > > define a LyXColorHandler::getGCForeground() that takes an RGB > > argument? It would shortcircuit part of the code and > > would call XAllocColor directly. > > > > Am I on a wild goose chase? > > This is definitely NOT the way to go. Remember though that for *my* purpose, all I want to do is specify an RGB colour and then paint it to the screen... nothing goes to LaTeX, nothing has syntactic significance for the LyX GUI. [Your original argument for making these colours just RGB triplets!] Making them complete infotab entries just feels a bit like overkill. Have a look at the attached patch. If I add methods fillRectangle and setBackgroundColor to the appropriate places ((X)Painter and InsetBranch) taking a string instead of an lcolor, then I am finished... any X11 colour (including #ff8a48!) can be directly painted as a branch inset background. Does this make sense? > > Why not use XAllocColor directly as it was made for this? > > Think of Qt running on a Windows box... ColorHandler is inside xforms only. And I am pretty sure that also other environments handle RGB values easier that the LyX specific LColors colours, and could be similarly adapted. > -- > Angus Martin
Index: ColorHandler.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/ColorHandler.C,v retrieving revision 1.14 diff -u -p -r1.14 ColorHandler.C --- ColorHandler.C 30 Jun 2003 23:56:12 -0000 1.14 +++ ColorHandler.C 4 Aug 2003 09:36:01 -0000 @@ -82,40 +82,33 @@ unsigned long LyXColorHandler::colorPixe } -// Gets GC according to color -// Uses caching -GC LyXColorHandler::getGCForeground(LColor::color c) +GC LyXColorHandler::getGCForeground(string const & s) { - if (colorGCcache[c] != 0) - return colorGCcache[c]; - XColor xcol; XColor ccol; - string const s = lcolor.getX11Name(c); XGCValues val; - // Look up the RGB values for the color, and an approximate // color that we can hope to get on this display. if (XLookupColor(display, colormap, s.c_str(), &xcol, &ccol) == 0) { lyxerr << bformat( - _("LyX: Unknown X11 color %1$s for %2$s\n" + _("LyX: Unknown X11 color %1$s\n" " Using black instead, sorry!"), - s, lcolor.getGUIName(c)) << endl; + s) << endl; unsigned long bla = BlackPixel(display, DefaultScreen(display)); val.foreground = bla; // Try the exact RGB values first, then the approximate. } else if (XAllocColor(display, colormap, &xcol) != 0) { if (lyxerr.debugging(Debug::GUI)) { - lyxerr << bformat(_("LyX: X11 color %1$s allocated for %2$s"), - s, lcolor.getGUIName(c)) << endl; + lyxerr << bformat(_("LyX: X11 color %1$s allocated"), + s) << endl; } val.foreground = xcol.pixel; } else if (XAllocColor(display, colormap, &ccol)) { lyxerr << bformat( - _("LyX: Using approximated X11 color %1$s allocated for %2$s"), - s, lcolor.getGUIName(c)) << endl; - val.foreground = xcol.pixel; + _("LyX: Using approximated X11 color %1$s"), + s) << endl; + val.foreground = ccol.pixel; } else { // Here we are traversing the current colormap to find // the color closest to the one we want. @@ -155,8 +148,8 @@ GC LyXColorHandler::getGCForeground(LCol } lyxerr << bformat( - _("LyX: Couldn't allocate '%1$s' for %2$s with (r,g,b)=%3$s.\n"), - s, lcolor.getGUIName(c), tostr(xcol)); + _("LyX: Couldn't allocate '%1$s' with (r,g,b)=%3$s.\n"), + s, tostr(xcol)); lyxerr << bformat( _(" Using closest allocated color with (r,g,b)=%1$s instead.\n" @@ -165,10 +158,29 @@ GC LyXColorHandler::getGCForeground(LCol val.foreground = cmap[closest_pixel].pixel; } - val.function = GXcopy; - return colorGCcache[c] = XCreateGC(display, drawable, + return XCreateGC(display, drawable, GCForeground | GCFunction, &val); +} + +// Gets GC according to color +// Uses caching +GC LyXColorHandler::getGCForeground(LColor::color c) +{ + if (colorGCcache[c] != 0) + return colorGCcache[c]; + + XColor xcol; + XColor ccol; + string const s = lcolor.getX11Name(c); + // Look up the RGB values for the color, and an approximate + // color that we can hope to get on this display. + if (XLookupColor(display, colormap, s.c_str(), &xcol, &ccol) == 0) { + lyxerr << bformat( + _("LyX: Unknown X11 color %1$s for %2$s\n"), + s, lcolor.getGUIName(c)) << endl; + } + return colorGCcache[c] = getGCForeground(s); } Index: ColorHandler.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/ColorHandler.h,v retrieving revision 1.6 diff -u -p -r1.6 ColorHandler.h --- ColorHandler.h 9 May 2003 09:43:38 -0000 1.6 +++ ColorHandler.h 4 Aug 2003 09:36:01 -0000 @@ -36,6 +36,8 @@ public: /// unsigned long colorPixel(LColor::color c); /// + GC LyXColorHandler::getGCForeground(string const & s); + /// GC getGCForeground(LColor::color c); /// GC getGCLinepars(Painter::line_style,
pgp00000.pgp
Description: PGP signature