Fixed Type Fonts - FC_DUAL or FC_MONO
Sander Jansen <[email protected]>
| Newsgroups | gmane.comp.lib.fox-toolkit.user |
|---|---|
| Message-ID | <CACj81kGTWf3CKbtQ=TopfCX6WA7YNuV+R+Bfd=rBJ=MJQaPd9Q@mail.gmail.com> |
(this is regarding the fontconfig / Xft backend) How can we deal with dual spaced fonts effectively? Right now, when trying to find a FXFont:Fixed type fonts occasionally get these weird doubled wide character spacing: [image: FC_MONO.png] Apparently this is solely based on whether the Fixed flag hint has been passed. In all 3 cases, it finds the exact same font. The current implementation uses the FC_MONO flag whenever we pass FXFont::Fixed. Apparently fontconfig also has a FC_DUAL flag (it seems to allow for multiple fixed sizes in a font), which seems to work better in this particular case: [image: FC_DUAL.png] (in a typical user interface, having mixed width characters like the above is pretty rare of course) So i've been wondering whether we should be using the FC_DUAL hint instead of FC_MONO. It certainly seems to behave much better from an end-user perspective (and does not require them to have a PHD in fontconfig nightmares). Thoughts? _______________________________________________ Foxgui-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/foxgui-users
FC_MONO.png
(image/png, 39.2 KB) - not displayed
FC_DUAL.png
(image/png, 36.9 KB) - not displayed
hello.cpp
(text/x-c++src, 5.2 KB)
#include "fx.h"
/*
This is a classical programming example. Doing it graphically
using FOX is, as you see, not a whole lot more involved than
its command-line equivalent!
Note the following things:
- Each FOX application needs one (and only one) application
object (FXApp).
- Before doing anything, the application object needs to be
initialized. You need to pass argc and argv so that certain
command line arguments may be filtered out by FOX (e.g. -display).
- You need to create at least one toplevel window; in this case,
that is FXMainWindow.
- FOX widgets are nested simply by creating them in the right order.
Here, we create FXButton as a child of "main."
- A single call to FXApp::create() will create X windows for each
widget. Until calling create(), a widget exists only at the client,
and has no associated X window yet.
- Finally, FXApp::run() will start the main event loop. This will
only return when the application is done.
*/
// The entry point where the program starts running
int main(int argc,char **argv){
// Each FOX GUI program needs one, and only one, application object.
// The application objects coordinates some common stuff shared between
// all the widgets; for example, it dispatches events, keeps track of
// all the windows, and so on.
// We pass the "name" of the application, and its "vendor", the name
// and vendor are used to search the registry database (which stores
// persistent information e.g. fonts and colors).
FXApp application("Hello","FoxTest");
// Here we initialize the application. We pass the command line arguments
// because FOX may sometimes need to filter out some of the arguments.
// This opens up the display as well, and reads the registry database
// so that persistent settings are now available.
application.init(argc,argv);
// This creates the main window. We pass in the title to be displayed
// above the window, and possibly some icons for when its iconified.
// The decorations determine stuff like the borders, close buttons,
// drag handles, and so on the Window Manager is supposed to give this
// window.
FXMainWindow *main=new FXMainWindow(&application,"Hello",nullptr,nullptr,DECOR_ALL,0,0,800,600);
// Here we create a button. The button has a label on it, but no icon in
// this case. An '&' followed by a letter introduces a hot-key so you can
// invoke this button from the keyboard.
// The button sends an ID_QUIT message to the application object, which
// in its default implementation causes the program to quit.
auto b1 = new FXButton(main,"Font 1",nullptr,&application,FXApp::ID_QUIT,JUSTIFY_LEFT|FRAME_THICK|FRAME_RAISED);
auto b2 = new FXButton(main,"Font 2",nullptr,&application,FXApp::ID_QUIT,JUSTIFY_LEFT|FRAME_THICK|FRAME_RAISED);
auto b3 = new FXButton(main,"Font 2",nullptr,&application,FXApp::ID_QUIT,JUSTIFY_LEFT|FRAME_THICK|FRAME_RAISED);
// This "realizes" the widget tree. This is necessary because GUI's are
// a client-server system, i.e. there are actually two programs involved,
// a client (in this case, "hello world"), and a server (The X11 server or
// Windows GDI). We can build our C++ widgets but something extra is needed
// to tell the server that we want windows on the screen. Besides windows,
// there are various other resources that need to be created, such as icons,
// fonts, and so on. This call recurses through the entire widget tree and
// creates them all, insofar as it can know about them.
application.create();
FXString ww1= "abcdefghijklmn - Modern\n\xe2\x91\xb4\xe2\x91\xb5\xe2\xb1\xa0\xea\x9c\xb2\xea\x9c\xb3\xea\x9c\xb4\xea\x9c\xb5\xea\x9c\xb6\xea\x9c\xb7\xea\x9c\xb8\xea\x9c\xb9";
FXString ww2 = "abcdefghijklmn - Modern|Variable\n\xe2\x91\xb4\xe2\x91\xb5\xe2\xb1\xa0\xea\x9c\xb2\xea\x9c\xb3\xea\x9c\xb4\xea\x9c\xb5\xea\x9c\xb6\xea\x9c\xb7\xea\x9c\xb8\xea\x9c\xb9";
FXString ww3 = "abcdefghijklmn - Modern|Fixed\n\xe2\x91\xb4\xe2\x91\xb5\xe2\xb1\xa0\xea\x9c\xb2\xea\x9c\xb3\xea\x9c\xb4\xea\x9c\xb5\xea\x9c\xb6\xea\x9c\xb7\xea\x9c\xb8\xea\x9c\xb9";
auto f1 = new FXFont(&application, "mono", 14, FXFont::Normal, FXFont::Straight, FONTENCODING_DEFAULT, FXFont::NonExpanded,FXFont::Modern);
f1->create();
b1->setFont(f1);
b1->setText(ww1 + f1->getActualName());
auto f2 = new FXFont(&application, "mono", 14, FXFont::Normal, FXFont::Straight, FONTENCODING_DEFAULT, FXFont::NonExpanded,FXFont::Variable|FXFont::Modern);
f2->create();
b2->setFont(f2);
b2->setText(ww2+f2->getActualName());
auto f3 = new FXFont(&application, "mono", 14, FXFont::Normal, FXFont::Straight, FONTENCODING_DEFAULT, FXFont::NonExpanded,FXFont::Fixed|FXFont::Modern);
f3->create();
b3->setFont(f3);
b3->setText(ww3 + f3->getActualName());
// Pretty self-explanatory:- this shows the window, and places it in the
// middle of the screen.
main->show(PLACEMENT_SCREEN);
// Now, we actually run the application. This does not return until we
// quit. The function run() is a simple loop which gets events from the
// user, executes them, and then waits for the next event, and so on until
// we hit the button.
return application.run();
}