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 <stdbool.h>
18
19 #include <gnome.h>
20 #include <ft2build.h>
21 #include FT_FREETYPE_H
22
23 #include "pflow.h"
24
25 #include "gnomeglue.h"
26
27 #include "arraymem.h"
28
29 struct Context
30 {
31 long width;
32 long height;
33 pf_flow *paragraph;
34 };
35
36 typedef struct Context Context;
37
38 static FT_Library engine;
39 static gs_guiSupport *guiSupport;
40 static fm_fontMap *fontMap;
41 static le_font *font;
42
43 static GSList *appList = NULL;
44
45 GtkWidget *newSample(const gchar *fileName);
46 void closeSample(GtkWidget *sample);
47
showabout(GtkWidget * widget,gpointer data)48 static void showabout(GtkWidget *widget, gpointer data)
49 {
50 GtkWidget *aboutBox;
51 const gchar *documentedBy[] = {NULL};
52 const gchar *writtenBy[] = {
53 "Eric Mader",
54 NULL
55 };
56
57 aboutBox = gnome_about_new("Gnome Layout Sample",
58 "0.1",
59 "Copyright (C) 1998-2006 By International Business Machines Corporation and others. All Rights Reserved.",
60 "A simple demo of the ICU LayoutEngine.",
61 writtenBy,
62 documentedBy,
63 "",
64 NULL);
65
66 gtk_widget_show(aboutBox);
67 }
68
69 #if 0
70 static void notimpl(GtkObject *object, gpointer data)
71 {
72 gnome_ok_dialog("Not implemented...");
73 }
74 #endif
75
prettyTitle(const gchar * path)76 static 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
openOK(GtkObject * object,gpointer data)84 static 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 pf_flow *newPara;
91
92 gtk_widget_destroy(GTK_WIDGET(fileselection));
93
94 newPara = pf_factory(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 pf_close(context->paragraph);
102 }
103
104 context->paragraph = newPara;
105 gtk_window_set_title(GTK_WINDOW(app), title);
106
107 gtk_widget_hide(area);
108 pf_breakLines(context->paragraph, context->width, context->height);
109 gtk_widget_show_all(area);
110
111 g_free(title);
112 }
113
114 g_free(fileName);
115 }
116
openfile(GtkObject * object,gpointer data)117 static 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
newapp(GtkObject * object,gpointer data)149 static void newapp(GtkObject *object, gpointer data)
150 {
151 GtkWidget *app = newSample("Sample.txt");
152
153 gtk_widget_show_all(app);
154 }
155
closeapp(GtkWidget * widget,gpointer data)156 static void closeapp(GtkWidget *widget, gpointer data)
157 {
158 GtkWidget *app = GTK_WIDGET(data);
159
160 closeSample(app);
161 }
162
shutdown(GtkObject * object,gpointer data)163 static 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
eventDelete(GtkWidget * widget,GdkEvent * event,gpointer data)195 static 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
eventConfigure(GtkWidget * widget,GdkEventConfigure * event,Context * context)203 static 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 pf_breakLines(context->paragraph, context->width, context->height);
211 }
212 }
213
214 return true;
215 }
216
eventExpose(GtkWidget * widget,GdkEvent * event,Context * context)217 static gint eventExpose(GtkWidget *widget, GdkEvent *event, Context *context)
218 {
219 if (context->paragraph != NULL) {
220 gint maxLines = pf_getLineCount(context->paragraph) - 1;
221 gint firstLine = 0, lastLine = context->height / pf_getLineHeight(context->paragraph);
222 rs_surface *surface = rs_gnomeRenderingSurfaceOpen(widget);
223
224 pf_draw(context->paragraph, surface, firstLine, (maxLines < lastLine)? maxLines : lastLine);
225
226 rs_gnomeRenderingSurfaceClose(surface);
227 }
228
229 return true;
230 }
231
newSample(const gchar * fileName)232 GtkWidget *newSample(const gchar *fileName)
233 {
234 Context *context = NEW_ARRAY(Context, 1);
235 gchar *title;
236 GtkWidget *app;
237 GtkWidget *area;
238 GtkStyle *style;
239 int i;
240
241 context->width = 600;
242 context->height = 400;
243 context->paragraph = pf_factory(fileName, font, guiSupport);
244
245 title = prettyTitle(fileName);
246 app = gnome_app_new("gnomeLayout", title);
247
248 gtk_object_set_data(GTK_OBJECT(app), "context", context);
249
250 gtk_window_set_default_size(GTK_WINDOW(app), 600 - 24, 400);
251
252 gnome_app_create_menus_with_data(GNOME_APP(app), mainMenu, app);
253
254 gtk_signal_connect(GTK_OBJECT(app), "delete_event",
255 GTK_SIGNAL_FUNC(eventDelete), NULL);
256
257 area = gtk_drawing_area_new();
258 gtk_object_set_data(GTK_OBJECT(app), "area", area);
259
260 style = gtk_style_copy(gtk_widget_get_style(area));
261
262 for (i = 0; i < 5; i += 1) {
263 style->fg[i] = style->white;
264 }
265
266 gtk_widget_set_style(area, style);
267
268 gnome_app_set_contents(GNOME_APP(app), area);
269
270 gtk_signal_connect(GTK_OBJECT(area),
271 "expose_event",
272 GTK_SIGNAL_FUNC(eventExpose),
273 context);
274
275 gtk_signal_connect(GTK_OBJECT(area),
276 "configure_event",
277 GTK_SIGNAL_FUNC(eventConfigure),
278 context);
279
280 appList = g_slist_prepend(appList, app);
281
282 g_free(title);
283
284 return app;
285 }
286
closeSample(GtkWidget * app)287 void closeSample(GtkWidget *app)
288 {
289 Context *context = (Context *) gtk_object_get_data(GTK_OBJECT(app), "context");
290
291 if (context->paragraph != NULL) {
292 pf_close(context->paragraph);
293 }
294
295 DELETE_ARRAY(context);
296
297 appList = g_slist_remove(appList, app);
298
299 gtk_widget_destroy(app);
300
301 if (appList == NULL) {
302 gtk_main_quit();
303 }
304 }
305
main(int argc,char * argv[])306 int main (int argc, char *argv[])
307 {
308 LEErrorCode fontStatus = LE_NO_ERROR;
309 poptContext ptctx;
310 GtkWidget *app;
311 const char *defaultArgs[] = {"Sample.txt", NULL};
312 const char **args;
313 int i;
314
315 FT_Init_FreeType(&engine);
316
317 gnome_init_with_popt_table("gnomelayout", "0.1", argc, argv, NULL, 0, &ptctx);
318
319 guiSupport = gs_gnomeGuiSupportOpen();
320 fontMap = fm_gnomeFontMapOpen(engine, "FontMap.Gnome", 24, guiSupport, &fontStatus);
321 font = le_scriptCompositeFontOpen(fontMap);
322
323 if (LE_FAILURE(fontStatus)) {
324 FT_Done_FreeType(engine);
325 return 1;
326 }
327
328 args = poptGetArgs(ptctx);
329
330 if (args == NULL) {
331 args = defaultArgs;
332 }
333
334 for (i = 0; args[i] != NULL; i += 1) {
335 app = newSample(args[i]);
336
337 gtk_widget_show_all(app);
338 }
339
340 poptFreeContext(ptctx);
341
342 gtk_main();
343
344 le_fontClose(font);
345 gs_gnomeGuiSupportClose(guiSupport);
346
347 FT_Done_FreeType(engine);
348
349 exit(0);
350 }
351