Home | History | Annotate | Download | only in layout
      1 
      2 /*
      3  ****************************************************************************** *
      4  *
      5  *   Copyright (C) 1999-2007, International Business Machines
      6  *   Corporation and others.  All Rights Reserved.
      7  *
      8  ****************************************************************************** *
      9  *   file name:  gnomelayout.cpp
     10  *
     11  *   created on: 09/04/2001
     12  *   created by: Eric R. Mader
     13  */
     14 
     15 #include <gnome.h>
     16 #include <ft2build.h>
     17 #include FT_FREETYPE_H
     18 
     19 #include "unicode/ustring.h"
     20 #include "unicode/uscript.h"
     21 
     22 #include "GnomeFontInstance.h"
     23 
     24 #include "paragraph.h"
     25 
     26 #include "GnomeGUISupport.h"
     27 #include "GnomeFontMap.h"
     28 #include "UnicodeReader.h"
     29 #include "ScriptCompositeFontInstance.h"
     30 
     31 #define ARRAY_LENGTH(array) (sizeof array / sizeof array[0])
     32 
     33 struct Context
     34 {
     35     long width;
     36     long height;
     37     Paragraph *paragraph;
     38 };
     39 
     40 static FT_Library engine;
     41 static GnomeGUISupport *guiSupport;
     42 static GnomeFontMap *fontMap;
     43 static ScriptCompositeFontInstance *font;
     44 
     45 static GSList *appList = NULL;
     46 
     47 GtkWidget *newSample(const gchar *fileName);
     48 void       closeSample(GtkWidget *sample);
     49 
     50 void showabout(GtkWidget */*widget*/, gpointer /*data*/)
     51 {
     52     GtkWidget *aboutBox;
     53     const gchar *documentedBy[] = {NULL};
     54     const gchar *writtenBy[] = {
     55         "Eric Mader",
     56         NULL
     57     };
     58 
     59     aboutBox = gnome_about_new("Gnome Layout Sample",
     60                                "0.1",
     61                                "Copyright (C) 1998-2006 By International Business Machines Corporation and others. All Rights Reserved.",
     62                                "A simple demo of the ICU LayoutEngine.",
     63                                writtenBy,
     64                                documentedBy,
     65                                "",
     66                                NULL);
     67 
     68     gtk_widget_show(aboutBox);
     69 }
     70 
     71 void notimpl(GtkObject */*object*/, gpointer /*data*/)
     72 {
     73     gnome_ok_dialog("Not implemented...");
     74 }
     75 
     76 gchar *prettyTitle(const gchar *path)
     77 {
     78   const gchar *name  = g_basename(path);
     79   gchar *title = g_strconcat("Gnome Layout Sample - ", name, NULL);
     80 
     81   return title;
     82 }
     83 
     84 void openOK(GtkObject */*object*/, gpointer data)
     85 {
     86   GtkFileSelection *fileselection = GTK_FILE_SELECTION(data);
     87   GtkWidget *app = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(fileselection), "app"));
     88   Context *context = (Context *) gtk_object_get_data(GTK_OBJECT(app), "context");
     89   gchar *fileName  = g_strdup(gtk_file_selection_get_filename(fileselection));
     90   Paragraph *newPara;
     91 
     92   gtk_widget_destroy(GTK_WIDGET(fileselection));
     93 
     94   newPara = Paragraph::paragraphFactory(fileName, font, guiSupport);
     95 
     96   if (newPara != NULL) {
     97     gchar *title = prettyTitle(fileName);
     98     GtkWidget *area = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(app), "area"));
     99 
    100     if (context->paragraph != NULL) {
    101       delete context->paragraph;
    102     }
    103 
    104     context->paragraph = newPara;
    105     gtk_window_set_title(GTK_WINDOW(app), title);
    106 
    107     gtk_widget_hide(area);
    108     context->paragraph->breakLines(context->width, context->height);
    109     gtk_widget_show_all(area);
    110 
    111     g_free(title);
    112   }
    113 
    114   g_free(fileName);
    115 }
    116 
    117 void openfile(GtkObject */*object*/, gpointer data)
    118 {
    119   GtkWidget *app = GTK_WIDGET(data);
    120   GtkWidget *fileselection;
    121   GtkWidget *okButton;
    122   GtkWidget *cancelButton;
    123 
    124   fileselection =
    125     gtk_file_selection_new("Open File");
    126 
    127   gtk_object_set_data(GTK_OBJECT(fileselection), "app", app);
    128 
    129   okButton =
    130     GTK_FILE_SELECTION(fileselection)->ok_button;
    131 
    132   cancelButton =
    133     GTK_FILE_SELECTION(fileselection)->cancel_button;
    134 
    135   gtk_signal_connect(GTK_OBJECT(fileselection), "destroy",
    136 		     GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
    137 
    138   gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
    139 		     GTK_SIGNAL_FUNC(openOK), fileselection);
    140 
    141   gtk_signal_connect_object(GTK_OBJECT(cancelButton), "clicked",
    142 		     GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(fileselection));
    143 
    144   gtk_window_set_modal(GTK_WINDOW(fileselection), TRUE);
    145   gtk_widget_show(fileselection);
    146   gtk_main();
    147 }
    148 
    149 void newapp(GtkObject */*object*/, gpointer /*data*/)
    150 {
    151   GtkWidget *app = newSample("Sample.txt");
    152 
    153   gtk_widget_show_all(app);
    154 }
    155 
    156 void closeapp(GtkWidget */*widget*/, gpointer data)
    157 {
    158   GtkWidget *app = GTK_WIDGET(data);
    159 
    160   closeSample(app);
    161 }
    162 
    163 void shutdown(GtkObject */*object*/, gpointer /*data*/)
    164 {
    165     gtk_main_quit();
    166 }
    167 
    168 GnomeUIInfo fileMenu[] =
    169 {
    170   GNOMEUIINFO_MENU_NEW_ITEM((gchar *) "_New Sample",
    171 			    (gchar *) "Create a new Gnome Layout Sample",
    172 			    newapp, NULL),
    173 
    174   GNOMEUIINFO_MENU_OPEN_ITEM(openfile, NULL),
    175   GNOMEUIINFO_SEPARATOR,
    176   GNOMEUIINFO_MENU_CLOSE_ITEM(closeapp, NULL),
    177   GNOMEUIINFO_MENU_EXIT_ITEM(shutdown, NULL),
    178   GNOMEUIINFO_END
    179 };
    180 
    181 GnomeUIInfo helpMenu[] =
    182 {
    183     // GNOMEUIINFO_HELP("gnomelayout"),
    184     GNOMEUIINFO_MENU_ABOUT_ITEM(showabout, NULL),
    185     GNOMEUIINFO_END
    186 };
    187 
    188 GnomeUIInfo mainMenu[] =
    189 {
    190     GNOMEUIINFO_SUBTREE(N_((gchar *) "File"), fileMenu),
    191     GNOMEUIINFO_SUBTREE(N_((gchar *) "Help"), helpMenu),
    192     GNOMEUIINFO_END
    193 };
    194 
    195 gint eventDelete(GtkWidget *widget, GdkEvent */*event*/, gpointer /*data*/)
    196 {
    197   closeSample(widget);
    198 
    199   // indicate that closeapp  already destroyed the window
    200   return TRUE;
    201 }
    202 
    203 gint eventConfigure(GtkWidget */*widget*/, GdkEventConfigure *event, Context *context)
    204 {
    205   if (context->paragraph != NULL) {
    206     context->width  = event->width;
    207     context->height = event->height;
    208 
    209     if (context->width > 0 && context->height > 0) {
    210         context->paragraph->breakLines(context->width, context->height);
    211     }
    212   }
    213 
    214   return TRUE;
    215 }
    216 
    217 gint eventExpose(GtkWidget *widget, GdkEvent */*event*/, Context *context)
    218 {
    219   if (context->paragraph != NULL) {
    220     gint maxLines = context->paragraph->getLineCount() - 1;
    221     gint firstLine = 0, lastLine = context->height / context->paragraph->getLineHeight();
    222     GnomeSurface surface(widget);
    223 
    224     context->paragraph->draw(&surface, firstLine, (maxLines < lastLine)? maxLines : lastLine);
    225   }
    226 
    227   return TRUE;
    228 }
    229 
    230 GtkWidget *newSample(const gchar *fileName)
    231 {
    232   Context   *context = new Context();
    233 
    234   context->width  = 600;
    235   context->height = 400;
    236   context->paragraph = Paragraph::paragraphFactory(fileName, font, guiSupport);
    237 
    238   gchar *title = prettyTitle(fileName);
    239   GtkWidget *app = gnome_app_new("gnomeLayout", title);
    240 
    241   gtk_object_set_data(GTK_OBJECT(app), "context", context);
    242 
    243   gtk_window_set_default_size(GTK_WINDOW(app), 600 - 24, 400);
    244 
    245   gnome_app_create_menus_with_data(GNOME_APP(app), mainMenu, app);
    246 
    247   gtk_signal_connect(GTK_OBJECT(app), "delete_event",
    248 		     GTK_SIGNAL_FUNC(eventDelete), NULL);
    249 
    250   GtkWidget *area = gtk_drawing_area_new();
    251   gtk_object_set_data(GTK_OBJECT(app), "area", area);
    252 
    253   GtkStyle *style = gtk_style_copy(gtk_widget_get_style(area));
    254 
    255   for (int i = 0; i < 5; i += 1) {
    256     style->fg[i] = style->white;
    257   }
    258 
    259   gtk_widget_set_style(area, style);
    260 
    261   gnome_app_set_contents(GNOME_APP(app), area);
    262 
    263   gtk_signal_connect(GTK_OBJECT(area),
    264 		     "expose_event",
    265 		     GTK_SIGNAL_FUNC(eventExpose),
    266 		     context);
    267 
    268   gtk_signal_connect(GTK_OBJECT(area),
    269 		     "configure_event",
    270 		     GTK_SIGNAL_FUNC(eventConfigure),
    271 		     context);
    272 
    273   appList = g_slist_prepend(appList, app);
    274 
    275   g_free(title);
    276 
    277   return app;
    278 }
    279 
    280 void closeSample(GtkWidget *app)
    281 {
    282   Context *context = (Context *) gtk_object_get_data(GTK_OBJECT(app), "context");
    283 
    284   if (context->paragraph != NULL) {
    285     delete context->paragraph;
    286   }
    287 
    288   delete context;
    289 
    290   appList = g_slist_remove(appList, app);
    291 
    292   gtk_widget_destroy(app);
    293 
    294   if (appList == NULL) {
    295     gtk_main_quit();
    296   }
    297 }
    298 
    299 int main (int argc, char *argv[])
    300 {
    301     LEErrorCode   fontStatus = LE_NO_ERROR;
    302     poptContext   ptctx;
    303     GtkWidget    *app;
    304 
    305     FT_Init_FreeType(&engine);
    306 
    307     gnome_init_with_popt_table("gnomelayout", "0.1", argc, argv, NULL, 0, &ptctx);
    308 
    309     guiSupport = new GnomeGUISupport();
    310     fontMap    = new GnomeFontMap(engine, "FontMap.Gnome", 24, guiSupport, fontStatus);
    311     font       = new ScriptCompositeFontInstance(fontMap);
    312 
    313     if (LE_FAILURE(fontStatus)) {
    314         FT_Done_FreeType(engine);
    315         return 1;
    316     }
    317 
    318     const char  *defaultArgs[] = {"Sample.txt", NULL};
    319     const char **args = poptGetArgs(ptctx);
    320 
    321     if (args == NULL) {
    322         args = defaultArgs;
    323     }
    324 
    325     for (int i = 0; args[i] != NULL; i += 1) {
    326        app = newSample(args[i]);
    327 
    328        gtk_widget_show_all(app);
    329     }
    330 
    331     poptFreeContext(ptctx);
    332 
    333     gtk_main();
    334 
    335     delete font;
    336     delete guiSupport;
    337 
    338     FT_Done_FreeType(engine);
    339 
    340     exit(0);
    341 }
    342