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