1 
2 /*
3  *******************************************************************************
4  *
5  *   © 2016 and later: Unicode, Inc. and others.
6  *   License & terms of use: http://www.unicode.org/copyright.html
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 
showabout(GtkWidget * widget,gpointer data)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 
prettyTitle(const gchar * path)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 
openOK(GtkObject * object,gpointer data)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 
openfile(GtkObject * object,gpointer data)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 
newapp(GtkObject * object,gpointer data)147 static void newapp(GtkObject *object, gpointer data)
148 {
149   GtkWidget *app = newSample("Sample.txt");
150 
151   gtk_widget_show_all(app);
152 }
153 
closeapp(GtkWidget * widget,gpointer data)154 static void closeapp(GtkWidget *widget, gpointer data)
155 {
156   GtkWidget *app = GTK_WIDGET(data);
157 
158   closeSample(app);
159 }
160 
shutdown(GtkObject * object,gpointer data)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 
eventDelete(GtkWidget * widget,GdkEvent * event,gpointer data)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 
eventConfigure(GtkWidget * widget,GdkEventConfigure * event,Context * context)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 
eventExpose(GtkWidget * widget,GdkEvent * event,Context * context)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 
newSample(const gchar * fileName)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 
closeSample(GtkWidget * app)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 
main(int argc,char * argv[])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