1
2 /*
3 *******************************************************************************
4 *
5 * Copyright (C) 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
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