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