aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-01-08 15:42:37 +0800
committerPo Lu2023-01-08 15:42:37 +0800
commit1584a58efd63d6806dbff51adcbfec054533b316 (patch)
treee0643f64d568fa2f8a6a0be757825fea08a80eda /src
parent86fe89312893bbc8aa47605afbf8da8cd5a12faf (diff)
downloademacs-1584a58efd63d6806dbff51adcbfec054533b316.tar.gz
emacs-1584a58efd63d6806dbff51adcbfec054533b316.zip
Update Android port
Note that the port currently does not work as of this check-in. * src/android.c (android_change_gc): Fix situations where clip rects are cleared. (android_create_pixmap_from_bitmap_data): Fix bitmap data iteration. * src/androidfns.c (Fx_show_tip, Fx_hide_tip): Remove annoying errors. * src/androidgui.h (enum android_event_type): (struct android_crossing_event): (struct android_motion_event): (struct android_button_event): (union android_event): New crossing, motion and button events. * src/androidterm.c (android_note_mouse_movement) (mouse_or_wdesc_frame, android_construct_mouse_click) (handle_one_android_event, android_mouse_position) (android_wait_for_event, android_set_window_size_1) (android_bitmap_icon, android_free_frame_resources) (syms_of_androidterm): New functions. Handle crossing, motion and button events. * src/androidterm.h (struct android_display_info): New field `last_mouse_movement_time'. (struct android_output): Remove unused `need_buffer_flip' field. * src/emacs.c (android_emacs_init): Initialize sfntfont. * src/frame.c (syms_of_frame): Set frame_inhibit_implied_resize to some reasonable value. * src/frame.h (GCALIGNED_STRUCT): Set wait_event_type on Android. * src/sfnt.c (eassert): (TEST_STATIC): (available): (enum sfnt_table): (sfnt_table_names): (SFNT_ENDOF): (struct sfnt_table_directory): (enum sfnt_scaler_type): (sfnt_coerce_fixed): (struct sfnt_hhea_table): (struct sfnt_cmap_table): (enum sfnt_platform_id): (enum sfnt_unicode_platform_specific_id): (enum sfnt_macintosh_platform_specific_id): (enum sfnt_microsoft_platform_specific_id): (struct sfnt_cmap_encoding_subtable): (struct sfnt_cmap_encoding_subtable_data): (struct sfnt_cmap_format_0): (struct sfnt_cmap_format_2_subheader): (struct sfnt_cmap_format_2): (struct sfnt_cmap_format_4): (struct sfnt_cmap_format_6): (struct sfnt_cmap_format_8_or_12_group): (struct sfnt_cmap_format_8): (struct sfnt_cmap_format_12): (struct sfnt_maxp_table): (struct sfnt_loca_table_short): (struct sfnt_loca_table_long): (struct sfnt_glyf_table): (struct sfnt_simple_glyph): (struct sfnt_compound_glyph_component): (struct sfnt_compound_glyph): (struct sfnt_glyph): (sfnt_read_table_directory): (file): (sfnt_read_cmap_table): (sfnt_read_head_table): (success): (sfnt_read_hhea_table): (sfnt_read_loca_table_short): (sfnt_read_loca_table_long): (sfnt_read_maxp_table): (sfnt_read_glyf_table): (sfnt_read_compound_glyph): (sfnt_read_glyph): (struct sfnt_point): (sfnt_expand_compound_glyph_context): (sfnt_decompose_compound_glyph): (struct sfnt_glyph_outline): (enum sfnt_glyph_outline_flags): (struct sfnt_build_glyph_outline_context): (sfnt_build_append): (sfnt_build_glyph_outline): (struct sfnt_raster): (struct sfnt_edge): (sfnt_prepare_raster): (sfnt_build_outline_edges): (sfnt_raster_glyph_outline): Move structures to sfnt.h. (struct sfnt_long_hor_metric): (struct sfnt_hmtx_table): (struct sfnt_glyph_metrics): (sfnt_read_hmtx_table): (sfnt_lookup_glyph_metrics): (sfnt_read_name_table): (sfnt_find_name): (sfnt_read_meta_table): (sfnt_find_metadata): (sfnt_test_edge_ignore): New functions. (main): Add new tests. * src/xdisp.c (redisplay_tool_bar):
Diffstat (limited to 'src')
-rw-r--r--src/android.c102
-rw-r--r--src/androidfns.c3
-rw-r--r--src/androidgui.h34
-rw-r--r--src/androidterm.c443
-rw-r--r--src/androidterm.h13
-rw-r--r--src/emacs.c8
-rw-r--r--src/frame.c2
-rw-r--r--src/frame.h5
-rw-r--r--src/sfnt.c1293
-rw-r--r--src/xdisp.c9
10 files changed, 1063 insertions, 849 deletions
diff --git a/src/android.c b/src/android.c
index db12e244275..e2056b666d6 100644
--- a/src/android.c
+++ b/src/android.c
@@ -1254,6 +1254,92 @@ NATIVE_NAME (sendWindowAction) (JNIEnv *env, jobject object,
1254 android_write_event (&event); 1254 android_write_event (&event);
1255} 1255}
1256 1256
1257extern JNIEXPORT void JNICALL
1258NATIVE_NAME (sendEnterNotify) (JNIEnv *env, jobject object,
1259 jshort window, jint x, jint y,
1260 jlong time)
1261{
1262 union android_event event;
1263
1264 event.xcrossing.type = ANDROID_ENTER_NOTIFY;
1265 event.xcrossing.window = window;
1266 event.xcrossing.x = x;
1267 event.xcrossing.y = y;
1268 event.xcrossing.time = time;
1269
1270 android_write_event (&event);
1271}
1272
1273extern JNIEXPORT void JNICALL
1274NATIVE_NAME (sendLeaveNotify) (JNIEnv *env, jobject object,
1275 jshort window, jint x, jint y,
1276 jlong time)
1277{
1278 union android_event event;
1279
1280 event.xcrossing.type = ANDROID_LEAVE_NOTIFY;
1281 event.xcrossing.window = window;
1282 event.xcrossing.x = x;
1283 event.xcrossing.y = y;
1284 event.xcrossing.time = time;
1285
1286 android_write_event (&event);
1287}
1288
1289extern JNIEXPORT void JNICALL
1290NATIVE_NAME (sendMotionNotify) (JNIEnv *env, jobject object,
1291 jshort window, jint x, jint y,
1292 jlong time)
1293{
1294 union android_event event;
1295
1296 event.xmotion.type = ANDROID_MOTION_NOTIFY;
1297 event.xmotion.window = window;
1298 event.xmotion.x = x;
1299 event.xmotion.y = y;
1300 event.xmotion.time = time;
1301
1302 android_write_event (&event);
1303}
1304
1305extern JNIEXPORT void JNICALL
1306NATIVE_NAME (sendButtonPress) (JNIEnv *env, jobject object,
1307 jshort window, jint x, jint y,
1308 jlong time, jint state,
1309 jint button)
1310{
1311 union android_event event;
1312
1313 event.xbutton.type = ANDROID_BUTTON_PRESS;
1314 event.xbutton.window = window;
1315 event.xbutton.x = x;
1316 event.xbutton.y = y;
1317 event.xbutton.time = time;
1318 event.xbutton.state = state;
1319 event.xbutton.button = button;
1320
1321 android_write_event (&event);
1322}
1323
1324extern JNIEXPORT void JNICALL
1325NATIVE_NAME (sendButtonRelease) (JNIEnv *env, jobject object,
1326 jshort window, jint x, jint y,
1327 jlong time, jint state,
1328 jint button)
1329{
1330 union android_event event;
1331
1332 event.xbutton.type = ANDROID_BUTTON_RELEASE;
1333 event.xbutton.window = window;
1334 event.xbutton.x = x;
1335 event.xbutton.y = y;
1336 event.xbutton.time = time;
1337 event.xbutton.state = state;
1338 event.xbutton.button = button;
1339
1340 android_write_event (&event);
1341}
1342
1257#pragma clang diagnostic pop 1343#pragma clang diagnostic pop
1258 1344
1259 1345
@@ -1747,12 +1833,11 @@ android_change_gc (struct android_gc *gc,
1747 emacs_gc_clip_mask, 1833 emacs_gc_clip_mask,
1748 what); 1834 what);
1749 1835
1750 /* Clearing GCClipMask also clears the clip rectangles. */ 1836 /* Changing GCClipMask also clears the clip rectangles. */
1751 if (!what) 1837 (*android_java_env)->SetObjectField (android_java_env,
1752 (*android_java_env)->SetObjectField (android_java_env, 1838 gcontext,
1753 gcontext, 1839 emacs_gc_clip_rects,
1754 emacs_gc_clip_rects, 1840 NULL);
1755 NULL);
1756 } 1841 }
1757 1842
1758 if (mask & ANDROID_GC_STIPPLE) 1843 if (mask & ANDROID_GC_STIPPLE)
@@ -2133,14 +2218,14 @@ android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
2133 /* The alpha channels must be set, or otherwise, the 2218 /* The alpha channels must be set, or otherwise, the
2134 pixmap will be created entirely transparent. */ 2219 pixmap will be created entirely transparent. */
2135 2220
2136 if (data[y * (width + 7) / 8 + x / 8] & (1 << (x % 8))) 2221 if (data[x / 8] & (1 << (x % 8)))
2137 region[x] = foreground | 0xff000000; 2222 region[x] = foreground | 0xff000000;
2138 else 2223 else
2139 region[x] = background | 0xff000000; 2224 region[x] = background | 0xff000000;
2140 } 2225 }
2141 else 2226 else
2142 { 2227 {
2143 if (data[y * (width + 7) / 8 + x / 8] & (1 << (x % 8))) 2228 if (data[x / 8] & (1 << (x % 8)))
2144 region[x] = foreground; 2229 region[x] = foreground;
2145 else 2230 else
2146 region[x] = background; 2231 region[x] = background;
@@ -2151,6 +2236,7 @@ android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
2151 colors, 2236 colors,
2152 width * y, width, 2237 width * y, width,
2153 region); 2238 region);
2239 data += width / 8;
2154 } 2240 }
2155 2241
2156 /* First, allocate the pixmap handle. */ 2242 /* First, allocate the pixmap handle. */
diff --git a/src/androidfns.c b/src/androidfns.c
index a78b35fc8ff..7fdb2f14141 100644
--- a/src/androidfns.c
+++ b/src/androidfns.c
@@ -1347,7 +1347,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
1347 error ("Android cross-compilation stub called!"); 1347 error ("Android cross-compilation stub called!");
1348 return Qnil; 1348 return Qnil;
1349#else 1349#else
1350 error ("Not implemented"); 1350 /* TODO tooltips */
1351 return Qnil; 1351 return Qnil;
1352#endif 1352#endif
1353} 1353}
@@ -1360,7 +1360,6 @@ DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
1360 error ("Android cross-compilation stub called!"); 1360 error ("Android cross-compilation stub called!");
1361 return Qnil; 1361 return Qnil;
1362#else 1362#else
1363 error ("Not implemented");
1364 return Qnil; 1363 return Qnil;
1365#endif 1364#endif
1366} 1365}
diff --git a/src/androidgui.h b/src/androidgui.h
index b0ea820cfdf..d51b73a764d 100644
--- a/src/androidgui.h
+++ b/src/androidgui.h
@@ -204,6 +204,11 @@ enum android_event_type
204 ANDROID_FOCUS_IN, 204 ANDROID_FOCUS_IN,
205 ANDROID_FOCUS_OUT, 205 ANDROID_FOCUS_OUT,
206 ANDROID_WINDOW_ACTION, 206 ANDROID_WINDOW_ACTION,
207 ANDROID_ENTER_NOTIFY,
208 ANDROID_LEAVE_NOTIFY,
209 ANDROID_MOTION_NOTIFY,
210 ANDROID_BUTTON_PRESS,
211 ANDROID_BUTTON_RELEASE,
207 }; 212 };
208 213
209struct android_any_event 214struct android_any_event
@@ -268,6 +273,32 @@ struct android_window_action_event
268 unsigned int action; 273 unsigned int action;
269}; 274};
270 275
276struct android_crossing_event
277{
278 enum android_event_type type;
279 android_window window;
280 int x, y;
281 unsigned long time;
282};
283
284struct android_motion_event
285{
286 enum android_event_type type;
287 android_window window;
288 int x, y;
289 unsigned long time;
290};
291
292struct android_button_event
293{
294 enum android_event_type type;
295 android_window window;
296 int x, y;
297 unsigned long time;
298 unsigned int state;
299 unsigned int button;
300};
301
271union android_event 302union android_event
272{ 303{
273 enum android_event_type type; 304 enum android_event_type type;
@@ -276,6 +307,9 @@ union android_event
276 struct android_configure_event xconfigure; 307 struct android_configure_event xconfigure;
277 struct android_focus_event xfocus; 308 struct android_focus_event xfocus;
278 struct android_window_action_event xaction; 309 struct android_window_action_event xaction;
310 struct android_crossing_event xcrossing;
311 struct android_motion_event xmotion;
312 struct android_button_event xbutton;
279}; 313};
280 314
281extern int android_pending (void); 315extern int android_pending (void);
diff --git a/src/androidterm.c b/src/androidterm.c
index 0279da4f58d..05fe7f01bf9 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -41,6 +41,11 @@ struct android_display_info *x_display_list;
41 41
42#include <android/log.h> 42#include <android/log.h>
43 43
44/* Non-zero means that a HELP_EVENT has been generated since Emacs
45 start. */
46
47static bool any_help_event_p;
48
44enum 49enum
45 { 50 {
46 ANDROID_EVENT_NORMAL, 51 ANDROID_EVENT_NORMAL,
@@ -261,6 +266,94 @@ android_detect_focus_change (struct android_display_info *dpyinfo,
261 } 266 }
262} 267}
263 268
269static bool
270android_note_mouse_movement (struct frame *frame,
271 struct android_motion_event *event)
272{
273 struct android_display_info *dpyinfo;
274 Emacs_Rectangle *r;
275
276 if (!FRAME_ANDROID_OUTPUT (frame))
277 return false;
278
279 dpyinfo = FRAME_DISPLAY_INFO (frame);
280 dpyinfo->last_mouse_motion_frame = frame;
281 dpyinfo->last_mouse_motion_x = event->x;
282 dpyinfo->last_mouse_motion_y = event->y;
283 dpyinfo->last_mouse_movement_time = event->time;
284
285 /* Has the mouse moved off the glyph it was on at the last sighting? */
286 r = &dpyinfo->last_mouse_glyph;
287 if (frame != dpyinfo->last_mouse_glyph_frame
288 || event->x < r->x || event->x >= r->x + r->width
289 || event->y < r->y || event->y >= r->y + r->height)
290 {
291 frame->mouse_moved = true;
292 /* TODO
293 dpyinfo->last_mouse_scroll_bar = NULL; */
294 note_mouse_highlight (frame, event->x, event->y);
295 /* Remember which glyph we're now on. */
296 remember_mouse_glyph (frame, event->x, event->y, r);
297 dpyinfo->last_mouse_glyph_frame = frame;
298 return true;
299 }
300
301 return false;
302}
303
304static struct frame *
305mouse_or_wdesc_frame (struct android_display_info *dpyinfo, int wdesc)
306{
307 struct frame *lm_f = (gui_mouse_grabbed (dpyinfo)
308 ? dpyinfo->last_mouse_frame
309 : NULL);
310
311 if (lm_f && !EQ (track_mouse, Qdropping)
312 && !EQ (track_mouse, Qdrag_source))
313 return lm_f;
314 else
315 {
316 struct frame *w_f = android_window_to_frame (dpyinfo, wdesc);
317
318 /* Do not return a tooltip frame. */
319 if (!w_f || FRAME_TOOLTIP_P (w_f))
320 return EQ (track_mouse, Qdropping) ? lm_f : NULL;
321 else
322 /* When dropping it would be probably nice to raise w_f
323 here. */
324 return w_f;
325 }
326}
327
328static Lisp_Object
329android_construct_mouse_click (struct input_event *result,
330 struct android_button_event *event,
331 struct frame *f)
332{
333 struct android_display_info *dpyinfo;
334 int x, y;
335
336 dpyinfo = FRAME_DISPLAY_INFO (f);
337 x = event->x;
338 y = event->y;
339
340 /* Make the event type NO_EVENT; we'll change that when we decide
341 otherwise. */
342 result->kind = MOUSE_CLICK_EVENT;
343 result->code = event->button - 1;
344 result->timestamp = event->time;
345 result->modifiers = (android_android_to_emacs_modifiers (dpyinfo,
346 event->state)
347 | (event->type == ANDROID_BUTTON_RELEASE
348 ? up_modifier : down_modifier));
349
350 XSETINT (result->x, x);
351 XSETINT (result->y, y);
352 XSETFRAME (result->frame_or_window, f);
353 result->arg = Qnil;
354 return Qnil;
355}
356
264static int 357static int
265handle_one_android_event (struct android_display_info *dpyinfo, 358handle_one_android_event (struct android_display_info *dpyinfo,
266 union android_event *event, int *finish, 359 union android_event *event, int *finish,
@@ -270,17 +363,20 @@ handle_one_android_event (struct android_display_info *dpyinfo,
270 struct frame *f, *any, *mouse_frame; 363 struct frame *f, *any, *mouse_frame;
271 Mouse_HLInfo *hlinfo; 364 Mouse_HLInfo *hlinfo;
272 union buffered_input_event inev; 365 union buffered_input_event inev;
273 int modifiers, count; 366 int modifiers, count, do_help;
274 367
275 /* It is okay for this to not resemble handle_one_xevent so much. 368 /* It is okay for this to not resemble handle_one_xevent so much.
276 Differences in event handling code are much less nasty than 369 Differences in event handling code are much less nasty than
277 stuble differences in the graphics code. */ 370 stuble differences in the graphics code. */
278 371
279 count = 0; 372 do_help = count = 0;
280 hlinfo = &dpyinfo->mouse_highlight; 373 hlinfo = &dpyinfo->mouse_highlight;
281 *finish = ANDROID_EVENT_NORMAL; 374 *finish = ANDROID_EVENT_NORMAL;
282 any = android_window_to_frame (dpyinfo, event->xany.window); 375 any = android_window_to_frame (dpyinfo, event->xany.window);
283 376
377 if (any && any->wait_event_type == event->type)
378 any->wait_event_type = 0; /* Indicates we got it. */
379
284 EVENT_INIT (inev.ie); 380 EVENT_INIT (inev.ie);
285 381
286 switch (event->type) 382 switch (event->type)
@@ -410,6 +506,213 @@ handle_one_android_event (struct android_display_info *dpyinfo,
410 /* A new frame must be created. */; 506 /* A new frame must be created. */;
411 } 507 }
412 508
509 case ANDROID_ENTER_NOTIFY:
510 f = any;
511
512 if (f)
513 android_note_mouse_movement (f, &event->xmotion);
514 goto OTHER;
515
516 case ANDROID_MOTION_NOTIFY:
517 f = any;
518
519 if (f)
520 {
521 /* Maybe generate a SELECT_WINDOW_EVENT for
522 `mouse-autoselect-window' but don't let popup menus
523 interfere with this (Bug#1261). */
524 if (!NILP (Vmouse_autoselect_window)
525 && !popup_activated ()
526 /* Don't switch if we're currently in the minibuffer.
527 This tries to work around problems where the
528 minibuffer gets unselected unexpectedly, and where
529 you then have to move your mouse all the way down to
530 the minibuffer to select it. */
531 && !MINI_WINDOW_P (XWINDOW (selected_window))
532 /* With `focus-follows-mouse' non-nil create an event
533 also when the target window is on another frame. */
534 && (f == XFRAME (selected_frame)
535 || !NILP (focus_follows_mouse)))
536 {
537 static Lisp_Object last_mouse_window;
538 Lisp_Object window
539 = window_from_coordinates (f, event->xmotion.x,
540 event->xmotion.y, 0,
541 false, false);
542
543 /* A window will be autoselected only when it is not
544 selected now and the last mouse movement event was
545 not in it. The remainder of the code is a bit vague
546 wrt what a "window" is. For immediate autoselection,
547 the window is usually the entire window but for GTK
548 where the scroll bars don't count. For delayed
549 autoselection the window is usually the window's text
550 area including the margins. */
551 if (WINDOWP (window)
552 && !EQ (window, last_mouse_window)
553 && !EQ (window, selected_window))
554 {
555 inev.ie.kind = SELECT_WINDOW_EVENT;
556 inev.ie.frame_or_window = window;
557 }
558
559 /* Remember the last window where we saw the mouse. */
560 last_mouse_window = window;
561 }
562
563 if (!android_note_mouse_movement (f, &event->xmotion))
564 help_echo_string = previous_help_echo_string;
565 }
566
567 /* If the contents of the global variable help_echo_string
568 has changed, generate a HELP_EVENT. */
569 if (!NILP (help_echo_string)
570 || !NILP (previous_help_echo_string))
571 do_help = 1;
572
573 if (f)
574 android_flush_dirty_back_buffer_on (f);
575
576 goto OTHER;
577
578 case ANDROID_LEAVE_NOTIFY:
579 f = any;
580
581 if (f)
582 {
583 /* Now clear dpyinfo->last_mouse_motion_frame, or
584 gui_redo_mouse_highlight will end up highlighting the
585 last known position of the mouse if a tooltip frame is
586 later unmapped. */
587
588 if (f == dpyinfo->last_mouse_motion_frame)
589 dpyinfo->last_mouse_motion_frame = NULL;
590
591 /* Something similar applies to
592 dpyinfo->last_mouse_glyph_frame. */
593 if (f == dpyinfo->last_mouse_glyph_frame)
594 dpyinfo->last_mouse_glyph_frame = NULL;
595
596 if (f == hlinfo->mouse_face_mouse_frame)
597 {
598 /* If we move outside the frame, then we're
599 certainly no longer on any text in the frame. */
600 clear_mouse_face (hlinfo);
601 hlinfo->mouse_face_mouse_frame = 0;
602 android_flush_dirty_back_buffer_on (f);
603 }
604
605 /* Generate a nil HELP_EVENT to cancel a help-echo.
606 Do it only if there's something to cancel.
607 Otherwise, the startup message is cleared when
608 the mouse leaves the frame. */
609 if (any_help_event_p
610 /* But never if `mouse-drag-and-drop-region' is in
611 progress, since that results in the tooltip being
612 dismissed when the mouse moves on top. */
613 && !((EQ (track_mouse, Qdrag_source)
614 || EQ (track_mouse, Qdropping))
615 && gui_mouse_grabbed (dpyinfo)))
616 do_help = -1;
617 }
618
619 goto OTHER;
620
621 case ANDROID_BUTTON_PRESS:
622 case ANDROID_BUTTON_RELEASE:
623 /* If we decide we want to generate an event to be seen
624 by the rest of Emacs, we put it here. */
625
626 f = any;
627
628 Lisp_Object tab_bar_arg = Qnil;
629 bool tab_bar_p = false;
630 bool tool_bar_p = false;
631
632 dpyinfo->last_mouse_glyph_frame = NULL;
633
634 f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
635
636 if (f)
637 {
638 /* Is this in the tab-bar? */
639 if (WINDOWP (f->tab_bar_window)
640 && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
641 {
642 Lisp_Object window;
643 int x = event->xbutton.x;
644 int y = event->xbutton.y;
645
646 window = window_from_coordinates (f, x, y, 0, true, true);
647 tab_bar_p = EQ (window, f->tab_bar_window);
648
649 if (tab_bar_p)
650 {
651 tab_bar_arg = handle_tab_bar_click
652 (f, x, y, (event->xbutton.type
653 == ANDROID_BUTTON_PRESS),
654 android_android_to_emacs_modifiers (dpyinfo,
655 event->xbutton.state));
656 android_flush_dirty_back_buffer_on (f);
657 }
658 }
659
660 /* Is this in the tool-bar? */
661 if (WINDOWP (f->tool_bar_window)
662 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
663 {
664 Lisp_Object window;
665 int x = event->xbutton.x;
666 int y = event->xbutton.y;
667
668 window = window_from_coordinates (f, x, y, 0, true, true);
669 tool_bar_p = (EQ (window, f->tool_bar_window)
670 && ((event->xbutton.type
671 != ANDROID_BUTTON_RELEASE)
672 || f->last_tool_bar_item != -1));
673
674 if (tool_bar_p && event->xbutton.button < 4)
675 {
676 handle_tool_bar_click
677 (f, x, y, (event->xbutton.type
678 == ANDROID_BUTTON_PRESS),
679 android_android_to_emacs_modifiers (dpyinfo,
680 event->xbutton.state));
681 android_flush_dirty_back_buffer_on (f);
682 }
683 }
684
685 if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
686 {
687 android_construct_mouse_click (&inev.ie, &event->xbutton, f);
688
689 if (!NILP (tab_bar_arg))
690 inev.ie.arg = tab_bar_arg;
691 }
692 }
693 else
694 {
695 /* TODO: scroll bars */
696 }
697
698 if (event->type == ANDROID_BUTTON_PRESS)
699 {
700 dpyinfo->grabbed |= (1 << event->xbutton.button);
701 dpyinfo->last_mouse_frame = f;
702 if (f && !tab_bar_p)
703 f->last_tab_bar_item = -1;
704 if (f && !tool_bar_p)
705 f->last_tool_bar_item = -1;
706 }
707 else
708 dpyinfo->grabbed &= ~(1 << event->xbutton.button);
709
710 /* Ignore any mouse motion that happened before this event;
711 any subsequent mouse-movement Emacs events should reflect
712 only motion after the ButtonPress/Release. */
713 if (f != 0)
714 f->mouse_moved = false;
715
413 goto OTHER; 716 goto OTHER;
414 717
415 default: 718 default:
@@ -423,6 +726,30 @@ handle_one_android_event (struct android_display_info *dpyinfo,
423 count++; 726 count++;
424 } 727 }
425 728
729 if (do_help
730 && !(hold_quit && hold_quit->kind != NO_EVENT))
731 {
732 Lisp_Object frame;
733
734 if (f)
735 XSETFRAME (frame, f);
736 else
737 frame = Qnil;
738
739 if (do_help > 0)
740 {
741 any_help_event_p = true;
742 gen_help_event (help_echo_string, frame, help_echo_window,
743 help_echo_object, help_echo_pos);
744 }
745 else
746 {
747 help_echo_string = Qnil;
748 gen_help_event (Qnil, frame, Qnil, Qnil, 0);
749 }
750 count++;
751 }
752
426 return count; 753 return count;
427} 754}
428 755
@@ -562,7 +889,32 @@ android_mouse_position (struct frame **fp, int insist,
562 enum scroll_bar_part *part, Lisp_Object *x, 889 enum scroll_bar_part *part, Lisp_Object *x,
563 Lisp_Object *y, Time *timestamp) 890 Lisp_Object *y, Time *timestamp)
564{ 891{
565 /* TODO */ 892 Lisp_Object tail, frame;
893 struct android_display_info *dpyinfo;
894
895 dpyinfo = FRAME_DISPLAY_INFO (*fp);
896
897 /* This is the best implementation possible on Android, where the
898 system doesn't let Emacs obtain any information about the mouse
899 pointer at all. */
900
901 if (dpyinfo->last_mouse_motion_frame)
902 {
903 *fp = dpyinfo->last_mouse_motion_frame;
904 *timestamp = dpyinfo->last_mouse_movement_time;
905 *x = make_fixnum (dpyinfo->last_mouse_motion_x);
906 *y = make_fixnum (dpyinfo->last_mouse_motion_y);
907 *bar_window = Qnil;
908 *part = scroll_bar_nowhere;
909
910 FOR_EACH_FRAME (tail, frame)
911 {
912 if (FRAME_ANDROID_P (XFRAME (frame)))
913 XFRAME (frame)->mouse_moved = false;
914 }
915
916 dpyinfo->last_mouse_motion_frame->mouse_moved = false;
917 }
566} 918}
567 919
568static Lisp_Object 920static Lisp_Object
@@ -679,6 +1031,45 @@ android_iconify_frame (struct frame *f)
679} 1031}
680 1032
681static void 1033static void
1034android_wait_for_event (struct frame *f, int eventtype)
1035{
1036 if (!FLOATP (Vandroid_wait_for_event_timeout))
1037 return;
1038
1039 int level = interrupt_input_blocked;
1040 struct timespec tmo, tmo_at, time_now;
1041
1042 f->wait_event_type = eventtype;
1043
1044 /* Default timeout is 0.1 second. Hopefully not noticeable. */
1045 double timeout = XFLOAT_DATA (Vandroid_wait_for_event_timeout);
1046 time_t timeout_seconds = (time_t) timeout;
1047 tmo = make_timespec (timeout_seconds,
1048 (long int) ((timeout - timeout_seconds)
1049 * 1000 * 1000 * 1000));
1050 tmo_at = timespec_add (current_timespec (), tmo);
1051
1052 while (f->wait_event_type)
1053 {
1054 pending_signals = true;
1055 totally_unblock_input ();
1056 /* XTread_socket is called after unblock. */
1057 block_input ();
1058 interrupt_input_blocked = level;
1059
1060 time_now = current_timespec ();
1061 if (timespec_cmp (tmo_at, time_now) < 0)
1062 break;
1063
1064 tmo = timespec_sub (tmo_at, time_now);
1065 if (android_select (0, NULL, NULL, NULL, &tmo, NULL) == 0)
1066 break; /* Timeout */
1067 }
1068
1069 f->wait_event_type = 0;
1070}
1071
1072static void
682android_set_window_size_1 (struct frame *f, bool change_gravity, 1073android_set_window_size_1 (struct frame *f, bool change_gravity,
683 int width, int height) 1074 int width, int height)
684{ 1075{
@@ -688,11 +1079,29 @@ android_set_window_size_1 (struct frame *f, bool change_gravity,
688 android_resize_window (FRAME_ANDROID_WINDOW (f), width, 1079 android_resize_window (FRAME_ANDROID_WINDOW (f), width,
689 height); 1080 height);
690 1081
691 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
692 receive in the ConfigureNotify event; if we get what we asked
693 for, then the event won't cause the screen to become garbaged, so
694 we have to make sure to do it here. */
695 SET_FRAME_GARBAGED (f); 1082 SET_FRAME_GARBAGED (f);
1083
1084 if (FRAME_VISIBLE_P (f))
1085 {
1086 android_wait_for_event (f, ANDROID_CONFIGURE_NOTIFY);
1087
1088 if (CONSP (frame_size_history))
1089 frame_size_history_extra (f, build_string ("set_window_size_1 visible"),
1090 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
1091 width, height, f->new_width, f->new_height);
1092 }
1093 else
1094 {
1095 if (CONSP (frame_size_history))
1096 frame_size_history_extra (f, build_string ("set_window_size_1 "
1097 "invisible"),
1098 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
1099 width, height, f->new_width, f->new_height);
1100
1101 adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
1102 FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
1103 5, 0, Qx_set_window_size_1);
1104 }
696} 1105}
697 1106
698void 1107void
@@ -792,7 +1201,6 @@ android_new_font (struct frame *f, Lisp_Object font_object, int fontset)
792static bool 1201static bool
793android_bitmap_icon (struct frame *f, Lisp_Object file) 1202android_bitmap_icon (struct frame *f, Lisp_Object file)
794{ 1203{
795 /* TODO */
796 return false; 1204 return false;
797} 1205}
798 1206
@@ -841,6 +1249,13 @@ android_free_frame_resources (struct frame *f)
841 if (f == hlinfo->mouse_face_mouse_frame) 1249 if (f == hlinfo->mouse_face_mouse_frame)
842 reset_mouse_highlight (hlinfo); 1250 reset_mouse_highlight (hlinfo);
843 1251
1252 /* These two need to be freed now that they are used to compute the
1253 mouse position, I think. */
1254 if (f == dpyinfo->last_mouse_motion_frame)
1255 dpyinfo->last_mouse_motion_frame = NULL;
1256 if (f == dpyinfo->last_mouse_frame)
1257 dpyinfo->last_mouse_frame = NULL;
1258
844 unblock_input (); 1259 unblock_input ();
845} 1260}
846 1261
@@ -3233,6 +3648,18 @@ syms_of_androidterm (void)
3233{ 3648{
3234 Fprovide (Qandroid, Qnil); 3649 Fprovide (Qandroid, Qnil);
3235 3650
3651 DEFVAR_LISP ("android-wait-for-event-timeout",
3652 Vandroid_wait_for_event_timeout,
3653 doc: /* How long to wait for Android events.
3654
3655Emacs will wait up to this many seconds to receive events after
3656making changes which affect the state of the graphical interface.
3657Under some situations this can take an indefinite amount of time,
3658so it is important to limit the wait.
3659
3660If set to a non-float value, there will be no wait at all. */);
3661 Vandroid_wait_for_event_timeout = make_float (0.1);
3662
3236 DEFVAR_BOOL ("x-use-underline-position-properties", 3663 DEFVAR_BOOL ("x-use-underline-position-properties",
3237 x_use_underline_position_properties, 3664 x_use_underline_position_properties,
3238 doc: /* SKIP: real doc in xterm.c. */); 3665 doc: /* SKIP: real doc in xterm.c. */);
diff --git a/src/androidterm.h b/src/androidterm.h
index c834ffb70e5..562dcdead17 100644
--- a/src/androidterm.h
+++ b/src/androidterm.h
@@ -129,6 +129,9 @@ struct android_display_info
129 129
130 /* Where the mouse was the last time the mouse moved. */ 130 /* Where the mouse was the last time the mouse moved. */
131 Emacs_Rectangle last_mouse_glyph; 131 Emacs_Rectangle last_mouse_glyph;
132
133 /* The time of the last mouse movement. */
134 Time last_mouse_movement_time;
132}; 135};
133 136
134struct android_output 137struct android_output
@@ -193,11 +196,6 @@ struct android_output
193 and inactive states. */ 196 and inactive states. */
194 bool_bf alpha_identical_p : 1; 197 bool_bf alpha_identical_p : 1;
195 198
196 /* Flag that indicates whether we've modified the back buffer and
197 need to publish our modifications to the front buffer at a
198 convenient time. */
199 bool_bf need_buffer_flip : 1;
200
201 /* Flag that indicates whether or not the frame contents are 199 /* Flag that indicates whether or not the frame contents are
202 complete and can be safely flushed while handling async 200 complete and can be safely flushed while handling async
203 input. */ 201 input. */
@@ -376,6 +374,11 @@ extern void syms_of_androidfont (void);
376 374
377extern void android_finalize_font_entity (struct font_entity *); 375extern void android_finalize_font_entity (struct font_entity *);
378 376
377/* Defined in sfntfont-android.c. */
378
379extern void init_sfntfont_android (void);
380extern void syms_of_sfntfont_android (void);
381
379 382
380 383
381#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) 384#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
diff --git a/src/emacs.c b/src/emacs.c
index 72b2e5e3dd0..e287ba53e13 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -37,6 +37,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
37#include "androidterm.h" 37#include "androidterm.h"
38#endif 38#endif
39 39
40#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
41#include "sfntfont.h"
42#endif
43
40#ifdef WINDOWSNT 44#ifdef WINDOWSNT
41#include <fcntl.h> 45#include <fcntl.h>
42#include <sys/socket.h> 46#include <sys/socket.h>
@@ -2396,6 +2400,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
2396 syms_of_fontset (); 2400 syms_of_fontset ();
2397#if !defined ANDROID_STUBIFY 2401#if !defined ANDROID_STUBIFY
2398 syms_of_androidfont (); 2402 syms_of_androidfont ();
2403 syms_of_sfntfont ();
2404 syms_of_sfntfont_android ();
2399#endif /* !ANDROID_STUBIFY */ 2405#endif /* !ANDROID_STUBIFY */
2400#endif /* HAVE_ANDROID */ 2406#endif /* HAVE_ANDROID */
2401 2407
@@ -2461,6 +2467,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
2461 2467
2462#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY 2468#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
2463 init_androidfont (); 2469 init_androidfont ();
2470 init_sfntfont ();
2471 init_sfntfont_android ();
2464#endif 2472#endif
2465 2473
2466 init_charset (); 2474 init_charset ();
diff --git a/src/frame.c b/src/frame.c
index ddb49219cbd..36a256f1f3d 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -6644,7 +6644,7 @@ implicitly when there's no window system support.
6644Note that when a frame is not large enough to accommodate a change of 6644Note that when a frame is not large enough to accommodate a change of
6645any of the parameters listed above, Emacs may try to enlarge the frame 6645any of the parameters listed above, Emacs may try to enlarge the frame
6646even if this option is non-nil. */); 6646even if this option is non-nil. */);
6647#if defined (HAVE_WINDOW_SYSTEM) 6647#if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_ANDROID)
6648#if defined (USE_GTK) || defined (HAVE_NS) 6648#if defined (USE_GTK) || defined (HAVE_NS)
6649 frame_inhibit_implied_resize = list1 (Qtab_bar_lines); 6649 frame_inhibit_implied_resize = list1 (Qtab_bar_lines);
6650#else 6650#else
diff --git a/src/frame.h b/src/frame.h
index d39a4d5e571..4405c2df860 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -599,8 +599,9 @@ struct frame
599 /* List of font-drivers available on the frame. */ 599 /* List of font-drivers available on the frame. */
600 struct font_driver_list *font_driver_list; 600 struct font_driver_list *font_driver_list;
601 601
602#if defined (HAVE_X_WINDOWS) 602#if defined HAVE_X_WINDOWS || defined HAVE_ANDROID
603 /* Used by x_wait_for_event when watching for an X event on this frame. */ 603 /* Used by x_wait_for_event when watching for an X event on this
604 frame. */
604 int wait_event_type; 605 int wait_event_type;
605#endif 606#endif
606 607
diff --git a/src/sfnt.c b/src/sfnt.c
index 9ac023ddba9..dfdc4f7acf8 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -20,7 +20,10 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 20
21#include <config.h> 21#include <config.h>
22 22
23#include "sfnt.h"
24
23#include <assert.h> 25#include <assert.h>
26#include <attribute.h>
24#include <byteswap.h> 27#include <byteswap.h>
25#include <fcntl.h> 28#include <fcntl.h>
26#include <intprops.h> 29#include <intprops.h>
@@ -54,14 +57,12 @@ xfree (void *ptr)
54 return free (ptr); 57 return free (ptr);
55} 58}
56 59
57static void 60/* Use this for functions that are static while building in test mode,
58eassert (bool condition) 61 but are used outside as well. */
59{ 62#define TEST_STATIC static
60 if (!condition)
61 abort ();
62}
63 63
64#else 64#else
65#define TEST_STATIC
65#include "lisp.h" 66#include "lisp.h"
66#endif 67#endif
67 68
@@ -75,33 +76,21 @@ eassert (bool condition)
75 libraries such as FreeType are not easily available, and the native 76 libraries such as FreeType are not easily available, and the native
76 font library is too limited for Emacs to support properly. 77 font library is too limited for Emacs to support properly.
77 78
78 Unlike most popular libraries for handling fonts, no "font" or 79 Unlike most popular libraries for handling fonts, no ``font'' or
79 "face" type is provided. Instead, routines and structure 80 ``face'' type is provided. Instead, routines and structure
80 definitions for accessing and making use of individual tables in a 81 definitions for accessing and making use of individual tables in a
81 font file are exported, which allows for flexibility in the rest of 82 font file are exported, which allows for flexibility in the rest of
82 Emacs. */ 83 Emacs.
83
84
85 84
86/* The sfnt container format is organized into different tables, such 85 Try not to keep this file too dependent on Emacs. Everything Lisp
87 as ``cmap'' or ``glyf''. Each of these tables has a specific 86 related goes in sfntfont.c. The author wants to keep using it for
88 format and use. These are all the tables known to Emacs. */ 87 some other (free) software. */
89 88
90enum sfnt_table 89
91 {
92 SFNT_TABLE_CMAP,
93 SFNT_TABLE_GLYF,
94 SFNT_TABLE_HEAD,
95 SFNT_TABLE_HHEA,
96 SFNT_TABLE_HMTX,
97 SFNT_TABLE_LOCA,
98 SFNT_TABLE_MAXP,
99 SFNT_TABLE_NAME,
100 };
101 90
102/* Mapping between sfnt table names and their identifiers. */ 91/* Mapping between sfnt table names and their identifiers. */
103 92
104uint32_t sfnt_table_names[] = 93static uint32_t sfnt_table_names[] =
105 { 94 {
106 [SFNT_TABLE_CMAP] = 0x636d6170, 95 [SFNT_TABLE_CMAP] = 0x636d6170,
107 [SFNT_TABLE_GLYF] = 0x676c7966, 96 [SFNT_TABLE_GLYF] = 0x676c7966,
@@ -111,580 +100,9 @@ uint32_t sfnt_table_names[] =
111 [SFNT_TABLE_LOCA] = 0x6c6f6361, 100 [SFNT_TABLE_LOCA] = 0x6c6f6361,
112 [SFNT_TABLE_MAXP] = 0x6d617870, 101 [SFNT_TABLE_MAXP] = 0x6d617870,
113 [SFNT_TABLE_NAME] = 0x6e616d65, 102 [SFNT_TABLE_NAME] = 0x6e616d65,
103 [SFNT_TABLE_META] = 0x6d657461,
114 }; 104 };
115 105
116#define SFNT_ENDOF(type, field, type1) \
117 ((size_t) offsetof (type, field) + sizeof (type1))
118
119/* Each of these structures must be aligned so that no compiler will
120 ever generate padding bytes on platforms where the alignment
121 requirements for uint32_t and uint16_t are no larger than 4 and 2
122 bytes respectively. */
123
124struct sfnt_offset_subtable
125{
126 /* The scaler type. */
127 uint32_t scaler_type;
128
129 /* The number of tables. */
130 uint16_t num_tables;
131
132 /* (Maximum power of 2 <= numTables) * 16. */
133 uint16_t search_range;
134
135 /* log2 (maximum power of 2 <= numTables) */
136 uint16_t entry_selector;
137
138 /* numTables * 16 - searchRange. */
139 uint16_t range_shift;
140
141 /* Variable length data. */
142 struct sfnt_table_directory *subtables;
143};
144
145/* The table directory. Follows the offset subtable, with one for
146 each table. */
147
148struct sfnt_table_directory
149{
150 /* 4-byte identifier for each table. See sfnt_table_names. */
151 uint32_t tag;
152
153 /* Table checksum. */
154 uint32_t checksum;
155
156 /* Offset from the start of the file. */
157 uint32_t offset;
158
159 /* Length of the table in bytes, not subject to padding. */
160 uint32_t length;
161};
162
163enum sfnt_scaler_type
164 {
165 SFNT_SCALER_TRUE = 0x74727565,
166 SFNT_SCALER_VER1 = 0x00010000,
167 SFNT_SCALER_TYP1 = 0x74797031,
168 SFNT_SCALER_OTTO = 0x4F54544F,
169 };
170
171typedef int32_t sfnt_fixed;
172typedef int16_t sfnt_fword;
173typedef uint16_t sfnt_ufword;
174
175#define sfnt_coerce_fixed(fixed) ((sfnt_fixed) (fixed) / 65535.0)
176
177typedef unsigned int sfnt_glyph;
178typedef unsigned int sfnt_char;
179
180struct sfnt_head_table
181{
182 /* The version. This is a 16.16 fixed point number. */
183 sfnt_fixed version;
184
185 /* The revision. */
186 sfnt_fixed revision;
187
188 /* Checksum adjustment. */
189 uint32_t checksum_adjustment;
190
191 /* Magic number, should be 0x5F0F3CF5. */
192 uint32_t magic;
193
194 /* Flags for the font. */
195 uint16_t flags;
196
197 /* Units per em. */
198 uint16_t units_per_em;
199
200 /* Time of creation. */
201 uint32_t created_high, created_low;
202
203 /* Time of modification. */
204 uint32_t modified_high, modified_low;
205
206 /* Minimum bounds. */
207 sfnt_fword xmin, ymin, xmax, ymax;
208
209 /* Mac specific stuff. */
210 uint16_t mac_style;
211
212 /* Smallest readable size in pixels. */
213 uint16_t lowest_rec_ppem;
214
215 /* Font direction hint. */
216 int16_t font_direction_hint;
217
218 /* Index to loc format. 0 for short offsets, 1 for long. */
219 int16_t index_to_loc_format;
220
221 /* Unused. */
222 int16_t glyph_data_format;
223};
224
225struct sfnt_hhea_table
226{
227 /* The version. This is a 16.16 fixed point number. */
228 sfnt_fixed version;
229
230 /* The maximum ascent and descent values for this font. */
231 sfnt_fword ascent, descent;
232
233 /* The typographic line gap. */
234 sfnt_fword line_gap;
235
236 /* The maximum advance width. */
237 sfnt_ufword advance_width_max;
238
239 /* The minimum bearings on either side. */
240 sfnt_fword min_left_side_bearing, min_right_side_bearing;
241
242 /* The maximum extent. */
243 sfnt_fword x_max_extent;
244
245 /* Caret slope. */
246 int16_t caret_slope_rise, caret_slope_run;
247
248 /* Caret offset for non slanted fonts. */
249 sfnt_fword caret_offset;
250
251 /* Reserved values. */
252 int16_t reserved1, reserved2, reserved3, reserved4;
253
254 /* Should always be zero. */
255 int16_t metric_data_format;
256
257 /* Number of advanced widths in metrics table. */
258 uint16_t num_of_long_hor_metrics;
259};
260
261struct sfnt_cmap_table
262{
263 /* Should be zero. */
264 uint16_t version;
265
266 /* Number of subtables. */
267 uint16_t num_subtables;
268};
269
270enum sfnt_platform_id
271 {
272 SFNT_PLATFORM_UNICODE = 0,
273 SFNT_PLATFORM_MACINTOSH = 1,
274 SFNT_PLATFORM_RESERVED = 2,
275 SFNT_PLATFORM_MICROSOFT = 3,
276 };
277
278enum sfnt_unicode_platform_specific_id
279 {
280 SFNT_UNICODE_1_0 = 0,
281 SFNT_UNICODE_1_1 = 1,
282 SFNT_UNICODE_ISO_10646_1993 = 2,
283 SFNT_UNICODE_2_0_BMP = 3,
284 SFNT_UNICODE_2_0 = 4,
285 SFNT_UNICODE_VARIATION_SEQUENCES = 5,
286 SFNT_UNICODE_LAST_RESORT = 6,
287 };
288
289enum sfnt_macintosh_platform_specific_id
290 {
291 SFNT_MACINTOSH_ROMAN = 0,
292 SFNT_MACINTOSH_JAPANESE = 1,
293 SFNT_MACINTOSH_TRADITIONAL_CHINESE = 2,
294 SFNT_MACINTOSH_KOREAN = 3,
295 SFNT_MACINTOSH_ARABIC = 4,
296 SFNT_MACINTOSH_HEBREW = 5,
297 SFNT_MACINTOSH_GREEK = 6,
298 SFNT_MACINTOSH_RUSSIAN = 7,
299 SFNT_MACINTOSH_RSYMBOL = 8,
300 SFNT_MACINTOSH_DEVANGARI = 9,
301 SFNT_MACINTOSH_GURMUKHI = 10,
302 SFNT_MACINTOSH_GUJARATI = 11,
303 SFNT_MACINTOSH_ORIYA = 12,
304 SFNT_MACINTOSH_BENGALI = 13,
305 SFNT_MACINTOSH_TAMIL = 14,
306 SFNT_MACINTOSH_TELUGU = 15,
307 SFNT_MACINTOSH_KANNADA = 16,
308 SFNT_MACINTOSH_MALAYALAM = 17,
309 SFNT_MACINTOSH_SINHALESE = 18,
310 SFNT_MACINTOSH_BURMESE = 19,
311 SFNT_MACINTOSH_KHMER = 20,
312 SFNT_MACINTOSH_THAI = 21,
313 SFNT_MACINTOSH_LAOTIAN = 22,
314 SFNT_MACINTOSH_GEORGIAN = 23,
315 SFNT_MACINTOSH_ARMENIAN = 24,
316 SFNT_MACINTOSH_SIMPLIFIED_CHINESE = 25,
317 SFNT_MACINTOSH_TIBETIAN = 26,
318 SFNT_MACINTOSH_MONGOLIAN = 27,
319 SFNT_MACINTOSH_GEEZ = 28,
320 SFNT_MACINTOSH_SLAVIC = 29,
321 SFNT_MACINTOSH_VIETNAMESE = 30,
322 SFNT_MACINTOSH_SINDHI = 31,
323 SFNT_MACINTOSH_UNINTERPRETED = 32,
324 };
325
326enum sfnt_microsoft_platform_specific_id
327 {
328 SFNT_MICROSOFT_SYMBOL = 0,
329 SFNT_MICROSOFT_UNICODE_BMP = 1,
330 SFNT_MICROSOFT_SHIFT_JIS = 2,
331 SFNT_MICROSOFT_PRC = 3,
332 SFNT_MICROSOFT_BIG_FIVE = 4,
333 SFNT_MICROSOFT_JOHAB = 5,
334 SFNT_MICROSOFT_UNICODE_UCS_4 = 6,
335 };
336
337struct sfnt_cmap_encoding_subtable
338{
339 /* The platform ID. */
340 uint16_t platform_id;
341
342 /* Platform specific ID. */
343 uint16_t platform_specific_id;
344
345 /* Mapping table offset. */
346 uint32_t offset;
347};
348
349struct sfnt_cmap_encoding_subtable_data
350{
351 /* Format and possibly the length in bytes. */
352 uint16_t format, length;
353};
354
355struct sfnt_cmap_format_0
356{
357 /* Format, set to 0. */
358 uint16_t format;
359
360 /* Length in bytes. Should be 262. */
361 uint16_t length;
362
363 /* Language code. */
364 uint16_t language;
365
366 /* Character code to glyph index map. */
367 uint8_t glyph_index_array[256];
368};
369
370struct sfnt_cmap_format_2_subheader
371{
372 uint16_t first_code;
373 uint16_t entry_count;
374 int16_t id_delta;
375 uint16_t id_range_offset;
376};
377
378struct sfnt_cmap_format_2
379{
380 /* Format, set to 2. */
381 uint16_t format;
382
383 /* Length in bytes. */
384 uint16_t length;
385
386 /* Language code. */
387 uint16_t language;
388
389 /* Array mapping high bytes to subheaders. */
390 uint16_t sub_header_keys[256];
391
392 /* Variable length data. */
393 struct sfnt_cmap_format_2_subheader *subheaders;
394 uint16_t *glyph_index_array;
395 uint16_t num_glyphs;
396};
397
398struct sfnt_cmap_format_4
399{
400 /* Format, set to 4. */
401 uint16_t format;
402
403 /* Length in bytes. */
404 uint16_t length;
405
406 /* Language code. */
407 uint16_t language;
408
409 /* 2 * seg_count. */
410 uint16_t seg_count_x2;
411
412 /* 2 * (2**FLOOR(log2(segCount))) */
413 uint16_t search_range;
414
415 /* log2(searchRange/2) */
416 uint16_t entry_selector;
417
418 /* Variable-length data. */
419 uint16_t *end_code;
420 uint16_t *reserved_pad;
421 uint16_t *start_code;
422 int16_t *id_delta;
423 int16_t *id_range_offset;
424 uint16_t *glyph_index_array;
425
426 /* The number of elements in glyph_index_array. */
427 size_t glyph_index_size;
428};
429
430struct sfnt_cmap_format_6
431{
432 /* Format, set to 6. */
433 uint16_t format;
434
435 /* Length in bytes. */
436 uint16_t length;
437
438 /* Language code. */
439 uint16_t language;
440
441 /* First character code in subrange. */
442 uint16_t first_code;
443
444 /* Number of character codes. */
445 uint16_t entry_count;
446
447 /* Variable-length data. */
448 uint16_t *glyph_index_array;
449};
450
451struct sfnt_cmap_format_8_or_12_group
452{
453 uint32_t start_char_code;
454 uint32_t end_char_code;
455 uint32_t start_glyph_code;
456};
457
458struct sfnt_cmap_format_8
459{
460 /* Format, set to 8. */
461 uint16_t format;
462
463 /* Reserved. */
464 uint16_t reserved;
465
466 /* Length in bytes. */
467 uint32_t length;
468
469 /* Language code. */
470 uint32_t language;
471
472 /* Tightly packed array of bits (8K bytes total) indicating whether
473 the particular 16-bit (index) value is the start of a 32-bit
474 character code. */
475 uint8_t is32[65536];
476
477 /* Number of groups. */
478 uint32_t num_groups;
479
480 /* Variable length data. */
481 struct sfnt_cmap_format_8_or_12_group *groups;
482};
483
484/* cmap formats 10, 13 and 14 unsupported. */
485
486struct sfnt_cmap_format_12
487{
488 /* Format, set to 12. */
489 uint16_t format;
490
491 /* Reserved. */
492 uint16_t reserved;
493
494 /* Length in bytes. */
495 uint32_t length;
496
497 /* Language code. */
498 uint32_t language;
499
500 /* Number of groups. */
501 uint32_t num_groups;
502
503 /* Variable length data. */
504 struct sfnt_cmap_format_8_or_12_group *groups;
505};
506
507struct sfnt_maxp_table
508{
509 /* Table version. */
510 sfnt_fixed version;
511
512 /* The number of glyphs in this font - 1. Set at version 0.5 or
513 later. */
514 uint16_t num_glyphs;
515
516 /* These fields are only set in version 1.0 or later. Maximum
517 points in a non-composite glyph. */
518 uint16_t max_points;
519
520 /* Maximum contours in a non-composite glyph. */
521 uint16_t max_contours;
522
523 /* Maximum points in a composite glyph. */
524 uint16_t max_composite_points;
525
526 /* Maximum contours in a composite glyph. */
527 uint16_t max_composite_contours;
528
529 /* 1 if instructions do not use the twilight zone (Z0), or 2 if
530 instructions do use Z0; should be set to 2 in most cases. */
531 uint16_t max_zones;
532
533 /* Maximum points used in Z0. */
534 uint16_t max_twilight_points;
535
536 /* Number of Storage Area locations. */
537 uint16_t max_storage;
538
539 /* Number of FDEFs, equal to the highest function number + 1. */
540 uint16_t max_function_defs;
541
542 /* Number of IDEFs. */
543 uint16_t max_instruction_defs;
544
545 /* Maximum stack depth across Font Program ('fpgm' table), CVT
546 Program ('prep' table) and all glyph instructions (in the 'glyf'
547 table). */
548 uint16_t max_stack_elements;
549
550 /* Maximum byte count for glyph instructions. */
551 uint16_t max_size_of_instructions;
552
553 /* Maximum number of components referenced at ``top level'' for any
554 composite glyph. */
555 uint16_t max_component_elements;
556
557 /* Maximum levels of recursion; 1 for simple components. */
558 uint16_t max_component_depth;
559};
560
561struct sfnt_loca_table_short
562{
563 /* Offsets to glyph data divided by two. */
564 uint16_t *offsets;
565
566 /* Size of the offsets list. */
567 size_t num_offsets;
568};
569
570struct sfnt_loca_table_long
571{
572 /* Offsets to glyph data. */
573 uint32_t *offsets;
574
575 /* Size of the offsets list. */
576 size_t num_offsets;
577};
578
579struct sfnt_glyf_table
580{
581 /* Size of the glyph data. */
582 size_t size;
583
584 /* Pointer to possibly unaligned glyph data. */
585 unsigned char *glyphs;
586};
587
588struct sfnt_simple_glyph
589{
590 /* The total number of points in this glyph. */
591 size_t number_of_points;
592
593 /* Array containing the last points of each contour. */
594 uint16_t *end_pts_of_contours;
595
596 /* Total number of bytes needed for instructions. */
597 uint16_t instruction_length;
598
599 /* Instruction data. */
600 uint8_t *instructions;
601
602 /* Array of flags. */
603 uint8_t *flags;
604
605 /* Array of X coordinates. */
606 int16_t *x_coordinates;
607
608 /* Array of Y coordinates. */
609 int16_t *y_coordinates;
610
611 /* Pointer to the end of that array. */
612 int16_t *y_coordinates_end;
613};
614
615struct sfnt_compound_glyph_component
616{
617 /* Compound glyph flags. */
618 uint16_t flags;
619
620 /* Component glyph index. */
621 uint16_t glyph_index;
622
623 /* X-offset for component or point number; type depends on bits 0
624 and 1 in component flags. */
625 union {
626 uint8_t a;
627 int8_t b;
628 uint16_t c;
629 int16_t d;
630 } argument1;
631
632 /* Y-offset for component or point number; type depends on bits 0
633 and 1 in component flags. */
634 union {
635 uint8_t a;
636 int8_t b;
637 uint16_t c;
638 int16_t d;
639 } argument2;
640
641 /* Various scale formats. */
642 union {
643 uint16_t scale;
644 struct {
645 uint16_t xscale;
646 uint16_t yscale;
647 } a;
648 struct {
649 uint16_t xscale;
650 uint16_t scale01;
651 uint16_t scale10;
652 uint16_t yscale;
653 } b;
654 } u;
655};
656
657struct sfnt_compound_glyph
658{
659 /* Pointer to array of components. */
660 struct sfnt_compound_glyph_component *components;
661
662 /* Number of elements in that array. */
663 size_t num_components;
664
665 /* Instruction data. */
666 uint8_t *instructions;
667
668 /* Length of instructions. */
669 uint16_t instruction_length;
670};
671
672struct sfnt_glyph
673{
674 /* Number of contours in this glyph. */
675 int16_t number_of_contours;
676
677 /* Coordinate bounds. */
678 sfnt_fword xmin, ymin, xmax, ymax;
679
680 /* Either a simple glyph or a compound glyph, depending on which is
681 set. */
682 struct sfnt_simple_glyph *simple;
683 struct sfnt_compound_glyph *compound;
684};
685
686
687
688/* Swap values from TrueType to system byte order. */ 106/* Swap values from TrueType to system byte order. */
689 107
690static void 108static void
@@ -710,7 +128,7 @@ _sfnt_swap32 (uint32_t *value)
710 the start of the file, and must be seekable. Return the table 128 the start of the file, and must be seekable. Return the table
711 directory upon success, else NULL. */ 129 directory upon success, else NULL. */
712 130
713static struct sfnt_offset_subtable * 131TEST_STATIC struct sfnt_offset_subtable *
714sfnt_read_table_directory (int fd) 132sfnt_read_table_directory (int fd)
715{ 133{
716 struct sfnt_offset_subtable *subtable; 134 struct sfnt_offset_subtable *subtable;
@@ -1375,7 +793,7 @@ sfnt_read_cmap_table_1 (int fd, uint32_t directory_offset,
1375 Return the CMAP table and a list of encoding subtables in 793 Return the CMAP table and a list of encoding subtables in
1376 *SUBTABLES and *DATA upon success, else NULL. */ 794 *SUBTABLES and *DATA upon success, else NULL. */
1377 795
1378static struct sfnt_cmap_table * 796TEST_STATIC struct sfnt_cmap_table *
1379sfnt_read_cmap_table (int fd, struct sfnt_offset_subtable *subtable, 797sfnt_read_cmap_table (int fd, struct sfnt_offset_subtable *subtable,
1380 struct sfnt_cmap_encoding_subtable **subtables, 798 struct sfnt_cmap_encoding_subtable **subtables,
1381 struct sfnt_cmap_encoding_subtable_data ***data) 799 struct sfnt_cmap_encoding_subtable_data ***data)
@@ -1732,7 +1150,7 @@ sfnt_lookup_glyph (sfnt_char character,
1732 1150
1733 Return the head table upon success, else NULL. */ 1151 Return the head table upon success, else NULL. */
1734 1152
1735static struct sfnt_head_table * 1153TEST_STATIC struct sfnt_head_table *
1736sfnt_read_head_table (int fd, struct sfnt_offset_subtable *subtable) 1154sfnt_read_head_table (int fd, struct sfnt_offset_subtable *subtable)
1737{ 1155{
1738 struct sfnt_table_directory *directory; 1156 struct sfnt_table_directory *directory;
@@ -1804,7 +1222,7 @@ sfnt_read_head_table (int fd, struct sfnt_offset_subtable *subtable)
1804 1222
1805 Return the head table upon success, else NULL. */ 1223 Return the head table upon success, else NULL. */
1806 1224
1807static struct sfnt_hhea_table * 1225TEST_STATIC struct sfnt_hhea_table *
1808sfnt_read_hhea_table (int fd, struct sfnt_offset_subtable *subtable) 1226sfnt_read_hhea_table (int fd, struct sfnt_offset_subtable *subtable)
1809{ 1227{
1810 struct sfnt_table_directory *directory; 1228 struct sfnt_table_directory *directory;
@@ -1870,7 +1288,7 @@ sfnt_read_hhea_table (int fd, struct sfnt_offset_subtable *subtable)
1870 1288
1871 Return the short table upon success, else NULL. */ 1289 Return the short table upon success, else NULL. */
1872 1290
1873static struct sfnt_loca_table_short * 1291TEST_STATIC struct sfnt_loca_table_short *
1874sfnt_read_loca_table_short (int fd, struct sfnt_offset_subtable *subtable) 1292sfnt_read_loca_table_short (int fd, struct sfnt_offset_subtable *subtable)
1875{ 1293{
1876 struct sfnt_table_directory *directory; 1294 struct sfnt_table_directory *directory;
@@ -1915,7 +1333,7 @@ sfnt_read_loca_table_short (int fd, struct sfnt_offset_subtable *subtable)
1915 1333
1916 Return the long table upon success, else NULL. */ 1334 Return the long table upon success, else NULL. */
1917 1335
1918static struct sfnt_loca_table_long * 1336TEST_STATIC struct sfnt_loca_table_long *
1919sfnt_read_loca_table_long (int fd, struct sfnt_offset_subtable *subtable) 1337sfnt_read_loca_table_long (int fd, struct sfnt_offset_subtable *subtable)
1920{ 1338{
1921 struct sfnt_table_directory *directory; 1339 struct sfnt_table_directory *directory;
@@ -1961,7 +1379,7 @@ sfnt_read_loca_table_long (int fd, struct sfnt_offset_subtable *subtable)
1961 Return the maxp table upon success, else NULL. If the version is 1379 Return the maxp table upon success, else NULL. If the version is
1962 0.5, fields past num_glyphs will not be populated. */ 1380 0.5, fields past num_glyphs will not be populated. */
1963 1381
1964static struct sfnt_maxp_table * 1382TEST_STATIC struct sfnt_maxp_table *
1965sfnt_read_maxp_table (int fd, struct sfnt_offset_subtable *subtable) 1383sfnt_read_maxp_table (int fd, struct sfnt_offset_subtable *subtable)
1966{ 1384{
1967 struct sfnt_table_directory *directory; 1385 struct sfnt_table_directory *directory;
@@ -2048,7 +1466,7 @@ sfnt_read_maxp_table (int fd, struct sfnt_offset_subtable *subtable)
2048 1466
2049 Return the glyf table upon success, else NULL. */ 1467 Return the glyf table upon success, else NULL. */
2050 1468
2051static struct sfnt_glyf_table * 1469TEST_STATIC struct sfnt_glyf_table *
2052sfnt_read_glyf_table (int fd, struct sfnt_offset_subtable *subtable) 1470sfnt_read_glyf_table (int fd, struct sfnt_offset_subtable *subtable)
2053{ 1471{
2054 struct sfnt_table_directory *directory; 1472 struct sfnt_table_directory *directory;
@@ -2545,6 +1963,9 @@ sfnt_read_compound_glyph (struct sfnt_glyph *glyph,
2545 data += sizeof words4; 1963 data += sizeof words4;
2546 } 1964 }
2547 1965
1966 /* Record the component flags. */
1967 glyph->compound->components[i].flags = flags;
1968
2548 i++; 1969 i++;
2549 } 1970 }
2550 while (flags & 040); /* MORE_COMPONENTS */ 1971 while (flags & 040); /* MORE_COMPONENTS */
@@ -2595,7 +2016,7 @@ sfnt_read_compound_glyph (struct sfnt_glyph *glyph,
2595 glyf table, using the offsets of LOCA_SHORT or LOCA_LONG, depending 2016 glyf table, using the offsets of LOCA_SHORT or LOCA_LONG, depending
2596 on which is non-NULL. */ 2017 on which is non-NULL. */
2597 2018
2598static struct sfnt_glyph * 2019TEST_STATIC struct sfnt_glyph *
2599sfnt_read_glyph (sfnt_glyph glyph_code, 2020sfnt_read_glyph (sfnt_glyph glyph_code,
2600 struct sfnt_glyf_table *glyf, 2021 struct sfnt_glyf_table *glyf,
2601 struct sfnt_loca_table_short *loca_short, 2022 struct sfnt_loca_table_short *loca_short,
@@ -2696,22 +2117,6 @@ sfnt_free_glyph (struct sfnt_glyph *glyph)
2696 2117
2697/* Glyph outline decomposition. */ 2118/* Glyph outline decomposition. */
2698 2119
2699struct sfnt_point
2700{
2701 /* X and Y in em space. */
2702 sfnt_fixed x, y;
2703};
2704
2705typedef void (*sfnt_move_to_proc) (struct sfnt_point, void *);
2706typedef void (*sfnt_line_to_proc) (struct sfnt_point, void *);
2707typedef void (*sfnt_curve_to_proc) (struct sfnt_point,
2708 struct sfnt_point,
2709 void *);
2710
2711typedef struct sfnt_glyph *(*sfnt_get_glyph_proc) (sfnt_glyph, void *,
2712 bool *);
2713typedef void (*sfnt_free_glyph_proc) (struct sfnt_glyph *, void *);
2714
2715/* Apply the transform in the compound glyph component COMPONENT to 2120/* Apply the transform in the compound glyph component COMPONENT to
2716 the array of points of length NUM_COORDINATES given as X and Y. */ 2121 the array of points of length NUM_COORDINATES given as X and Y. */
2717 2122
@@ -2834,7 +2239,8 @@ sfnt_expand_compound_glyph_context (struct sfnt_compound_glyph_context *context,
2834 size_bytes); 2239 size_bytes);
2835 context->y_coordinates = xrealloc (context->y_coordinates, 2240 context->y_coordinates = xrealloc (context->y_coordinates,
2836 size_bytes); 2241 size_bytes);
2837 context->flags = xrealloc (context->flags, context->num_points); 2242 context->flags = xrealloc (context->flags,
2243 context->points_size);
2838 } 2244 }
2839 2245
2840 /* Set x_base and y_base. */ 2246 /* Set x_base and y_base. */
@@ -2900,7 +2306,7 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2900 void *dcontext) 2306 void *dcontext)
2901{ 2307{
2902 struct sfnt_glyph *subglyph; 2308 struct sfnt_glyph *subglyph;
2903 int i, rc; 2309 int i, j, rc;
2904 bool need_free; 2310 bool need_free;
2905 struct sfnt_compound_glyph_component *component; 2311 struct sfnt_compound_glyph_component *component;
2906 sfnt_fixed x, y, xtemp, ytemp; 2312 sfnt_fixed x, y, xtemp, ytemp;
@@ -2918,10 +2324,10 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2918 /* Set up the base index. */ 2324 /* Set up the base index. */
2919 base_index = context->num_points; 2325 base_index = context->num_points;
2920 2326
2921 for (i = 0; i < glyph->compound->num_components; ++i) 2327 for (j = 0; j < glyph->compound->num_components; ++j)
2922 { 2328 {
2923 /* Look up the associated subglyph. */ 2329 /* Look up the associated subglyph. */
2924 component = &glyph->compound->components[i]; 2330 component = &glyph->compound->components[j];
2925 subglyph = get_glyph (component->glyph_index, 2331 subglyph = get_glyph (component->glyph_index,
2926 dcontext, &need_free); 2332 dcontext, &need_free);
2927 2333
@@ -3345,49 +2751,6 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
3345 return 1; 2751 return 1;
3346} 2752}
3347 2753
3348/* Structure describing a single recorded outline in fixed pixel
3349 space. */
3350
3351struct sfnt_glyph_outline
3352{
3353 /* Packed outline data. This is made of aligned, signed, 4 byte
3354 words. The first word is a number containing flags. The second
3355 and third words are a point in 16.16 fixed format. */
3356 int *outline;
3357
3358 /* Size of the outline data in word increments, and how much is
3359 full. */
3360 size_t outline_size, outline_used;
3361
3362 /* Rectangle defining bounds of the outline. Namely, the minimum
3363 and maximum X and Y positions. */
3364 sfnt_fixed xmin, ymin, xmax, ymax;
3365};
3366
3367enum sfnt_glyph_outline_flags
3368 {
3369 SFNT_GLYPH_OUTLINE_LINETO = (1 << 1),
3370 };
3371
3372struct sfnt_build_glyph_outline_context
3373{
3374 /* The outline being built. */
3375 struct sfnt_glyph_outline *outline;
3376
3377 /* The head table. */
3378 struct sfnt_head_table *head;
3379
3380 /* The pixel size being used, and any extra flags to apply to the
3381 outline at this point. */
3382 int pixel_size;
3383
3384 /* Factor to multiply positions by to get the pixel width. */
3385 double factor;
3386
3387 /* The position of the pen in 16.16 fixed point format. */
3388 sfnt_fixed x, y;
3389};
3390
3391/* Global state for sfnt_build_glyph_outline and related 2754/* Global state for sfnt_build_glyph_outline and related
3392 functions. */ 2755 functions. */
3393static struct sfnt_build_glyph_outline_context build_outline_context; 2756static struct sfnt_build_glyph_outline_context build_outline_context;
@@ -3397,7 +2760,7 @@ static struct sfnt_build_glyph_outline_context build_outline_context;
3397 memory. */ 2760 memory. */
3398 2761
3399static struct sfnt_glyph_outline * 2762static struct sfnt_glyph_outline *
3400sfnt_build_append (unsigned int flags, unsigned int x, unsigned int y) 2763sfnt_build_append (int flags, sfnt_fixed x, sfnt_fixed y)
3401{ 2764{
3402 struct sfnt_glyph_outline *outline; 2765 struct sfnt_glyph_outline *outline;
3403 2766
@@ -3407,7 +2770,7 @@ sfnt_build_append (unsigned int flags, unsigned int x, unsigned int y)
3407 return build_outline_context.outline; 2770 return build_outline_context.outline;
3408 2771
3409 outline = build_outline_context.outline; 2772 outline = build_outline_context.outline;
3410 outline->outline_used += 3; 2773 outline->outline_used++;
3411 2774
3412 /* See if the outline has to be extended. Checking for overflow 2775 /* See if the outline has to be extended. Checking for overflow
3413 should not be necessary. */ 2776 should not be necessary. */
@@ -3420,13 +2783,14 @@ sfnt_build_append (unsigned int flags, unsigned int x, unsigned int y)
3420 outline = xrealloc (outline, (sizeof *outline 2783 outline = xrealloc (outline, (sizeof *outline
3421 + (outline->outline_size 2784 + (outline->outline_size
3422 * sizeof *outline->outline))); 2785 * sizeof *outline->outline)));
3423 outline->outline = (int *) (outline + 1); 2786 outline->outline
2787 = (struct sfnt_glyph_outline_command *) (outline + 1);
3424 } 2788 }
3425 2789
3426 /* Write the outline data. */ 2790 /* Write the outline data. */
3427 outline->outline[outline->outline_used - 3] = flags; 2791 outline->outline[outline->outline_used - 1].flags = flags;
3428 outline->outline[outline->outline_used - 2] = x; 2792 outline->outline[outline->outline_used - 1].x = x;
3429 outline->outline[outline->outline_used - 1] = y; 2793 outline->outline[outline->outline_used - 1].y = y;
3430 2794
3431 /* Extend outline bounding box. */ 2795 /* Extend outline bounding box. */
3432 2796
@@ -3650,7 +3014,7 @@ sfnt_curve_to_and_build (struct sfnt_point control,
3650 3014
3651 HEAD should be the `head' table of the font. */ 3015 HEAD should be the `head' table of the font. */
3652 3016
3653static struct sfnt_glyph_outline * 3017TEST_STATIC struct sfnt_glyph_outline *
3654sfnt_build_glyph_outline (struct sfnt_glyph *glyph, 3018sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3655 struct sfnt_head_table *head, 3019 struct sfnt_head_table *head,
3656 int pixel_size, 3020 int pixel_size,
@@ -3662,10 +3026,11 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3662 int rc; 3026 int rc;
3663 3027
3664 /* Allocate the outline now with enough for 44 words at the end. */ 3028 /* Allocate the outline now with enough for 44 words at the end. */
3665 outline = xmalloc (sizeof *outline + 44 * sizeof (unsigned int)); 3029 outline = xmalloc (sizeof *outline + 40 * sizeof (*outline->outline));
3666 outline->outline_size = 44; 3030 outline->outline_size = 40;
3667 outline->outline_used = 0; 3031 outline->outline_used = 0;
3668 outline->outline = (int *) (outline + 1); 3032 outline->outline
3033 = (struct sfnt_glyph_outline_command *) (outline + 1);
3669 3034
3670 /* DCONTEXT will be passed to GET_GLYPH and FREE_GLYPH, so global 3035 /* DCONTEXT will be passed to GET_GLYPH and FREE_GLYPH, so global
3671 variables must be used to communicate with the decomposition 3036 variables must be used to communicate with the decomposition
@@ -3722,50 +3087,6 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3722 Then, a bog standard edge filler is used to turn them into 3087 Then, a bog standard edge filler is used to turn them into
3723 spans. */ 3088 spans. */
3724 3089
3725struct sfnt_raster
3726{
3727 /* Basic dimensions of the raster. */
3728 unsigned short width, height;
3729
3730 /* Integer offset to apply to positions in the raster. */
3731 unsigned short offx, offy;
3732
3733 /* Pointer to coverage data. */
3734 unsigned char *cells;
3735};
3736
3737struct sfnt_edge
3738{
3739 /* Next edge in this chain. */
3740 struct sfnt_edge *next;
3741
3742 /* Winding direction. 1 if clockwise, -1 if counterclockwise. */
3743 int winding;
3744
3745 /* inc_x is which direction (left or right) a vector from this edge
3746 to the edge on top goes. */
3747 int inc_x;
3748
3749 /* X position, top and bottom of edges. */
3750 sfnt_fixed x, top, bottom;
3751
3752 /* DX and DY are the total delta between this edge and the next edge
3753 on top. */
3754 sfnt_fixed dx, dy;
3755
3756 /* step_x is how many pixels to move for each increase in Y. */
3757 sfnt_fixed step_x;
3758};
3759
3760enum
3761 {
3762 SFNT_POLY_SHIFT = 2,
3763 SFNT_POLY_SAMPLE = (1 << SFNT_POLY_SHIFT),
3764 SFNT_POLY_MASK = (SFNT_POLY_SAMPLE - 1),
3765 SFNT_POLY_STEP = (0x10000 >> SFNT_POLY_SHIFT),
3766 SFNT_POLY_START = (SFNT_POLY_STEP >> 1),
3767 };
3768
3769/* Coverage table. This is a four dimensional array indiced by the Y, 3090/* Coverage table. This is a four dimensional array indiced by the Y,
3770 then X axis fractional, shifted down to 2 bits. */ 3091 then X axis fractional, shifted down to 2 bits. */
3771 3092
@@ -3802,7 +3123,7 @@ sfnt_prepare_raster (struct sfnt_raster *raster,
3802 raster->offx 3123 raster->offx
3803 = sfnt_floor_fixed (outline->xmin); 3124 = sfnt_floor_fixed (outline->xmin);
3804 raster->offy 3125 raster->offy
3805 = sfnt_floor_fixed (outline->xmax); 3126 = sfnt_floor_fixed (raster->height - outline->ymax);
3806} 3127}
3807 3128
3808typedef void (*sfnt_edge_proc) (struct sfnt_edge *, size_t, 3129typedef void (*sfnt_edge_proc) (struct sfnt_edge *, size_t,
@@ -3831,39 +3152,37 @@ sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3831{ 3152{
3832 struct sfnt_edge *edges; 3153 struct sfnt_edge *edges;
3833 size_t i, edge, start, next_vertex, y; 3154 size_t i, edge, start, next_vertex, y;
3155 sfnt_fixed dx, dy, bot;
3156 int inc_x;
3157 size_t top, bottom;
3834 3158
3835 eassert (!(outline->outline_used % 3)); 3159 edges = alloca (outline->outline_used * sizeof *edges);
3836
3837 /* outline->outline uses 3 words for each point. */
3838 edges = alloca (outline->outline_used / 3 * sizeof *edges);
3839 edge = 0; 3160 edge = 0;
3840 3161
3841 /* First outline currently being processed. */ 3162 /* First outline currently being processed. */
3842 start = 0; 3163 start = 0;
3843 3164
3844 for (i = 0; i < outline->outline_used; i += 3) 3165 for (i = 0; i < outline->outline_used; i++)
3845 { 3166 {
3846 if (!(outline->outline[i] & SFNT_GLYPH_OUTLINE_LINETO)) 3167 if (!(outline->outline[i].flags & SFNT_GLYPH_OUTLINE_LINETO))
3847 /* Flush the edge. */ 3168 /* Flush the edge. */
3848 start = i; 3169 start = i;
3849 3170
3850 /* Set NEXT_VERTEX to the next point (vertex) in this contour. 3171 /* Set NEXT_VERTEX to the next point (vertex) in this contour.
3851 If i + 3 is the end of the contour, then the next point is 3172 If i + 3 is the end of the contour, then the next point is
3852 its start, so wrap it around to there. */ 3173 its start, so wrap it around to there. */
3853 next_vertex = i + 3; 3174 next_vertex = i + 1;
3854 if (next_vertex == outline->outline_used 3175 if (next_vertex == outline->outline_used
3855 || !(outline->outline[next_vertex] 3176 || !(outline->outline[next_vertex].flags
3856 & SFNT_GLYPH_OUTLINE_LINETO)) 3177 & SFNT_GLYPH_OUTLINE_LINETO))
3857 next_vertex = start; 3178 next_vertex = start;
3858 3179
3859 /* Skip past horizontal vertices. */ 3180 /* Skip past horizontal vertices. */
3860 if (outline->outline[next_vertex + 2] /* next_vertex->y */ 3181 if (outline->outline[next_vertex].y == outline->outline[i].y)
3861 == outline->outline[i + 2])
3862 continue; 3182 continue;
3863 3183
3864 /* Figure out the winding direction. */ 3184 /* Figure out the winding direction. */
3865 if (outline->outline[next_vertex + 2] /* next_vertex->y */ 3185 if (outline->outline[next_vertex].y < outline->outline[i].y)
3866 < outline->outline[i + 2])
3867 /* Vector will cross imaginary ray from its bottom from the 3186 /* Vector will cross imaginary ray from its bottom from the
3868 left of the ray. Winding is thus 1. */ 3187 left of the ray. Winding is thus 1. */
3869 edges[edge].winding = 1; 3188 edges[edge].winding = 1;
@@ -3876,68 +3195,49 @@ sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3876 If the next edge is above, then top is there and this is the 3195 If the next edge is above, then top is there and this is the
3877 bottom. */ 3196 bottom. */
3878 3197
3879 if (outline->outline[next_vertex + 2] < outline->outline[i + 2]) 3198 if (outline->outline[next_vertex].y < outline->outline[i].y)
3880 { 3199 {
3881 /* Next edge is below this one (keep in mind this is a 3200 /* End of edge is below this one (keep in mind this is a
3882 cartesian coordinate system, so smaller values are below 3201 cartesian coordinate system, so smaller values are below
3883 larger ones.) */ 3202 larger ones.) */
3884 edges[edge].top = (outline->outline[i + 2] 3203 top = i;
3885 - outline->ymin); 3204 bottom = next_vertex;
3886 edges[edge].bottom = (outline->outline[next_vertex + 2]
3887 - outline->ymin);
3888
3889 /* Record the edge. Rasterization happens from bottom to
3890 up, so record the X at the bottom. */
3891 edges[edge].x = (outline->outline[next_vertex + 1]
3892 - outline->xmin);
3893
3894 eassert (edges[edge].top >= edges[edge].bottom);
3895
3896 edges[edge].dx = (outline->outline[i + 1]
3897 - outline->outline[next_vertex + 1]);
3898 } 3205 }
3899 else 3206 else
3900 { 3207 {
3901 /* Next edge is below this one. */ 3208 /* End of edge is above this one. */
3902 edges[edge].bottom = (outline->outline[i + 2] 3209 bottom = i;
3903 - outline->ymin); 3210 top = next_vertex;
3904 edges[edge].top = (outline->outline[next_vertex + 2]
3905 - outline->ymin);
3906
3907 /* Record the edge. Rasterization happens from bottom to
3908 up, so record the X at the bottom. */
3909 edges[edge].x = (outline->outline[i + 1]
3910 - outline->xmin);
3911
3912 eassert (edges[edge].top >= edges[edge].bottom);
3913
3914 edges[edge].dx = (outline->outline[next_vertex + 1]
3915 - outline->outline[i + 1]);
3916 } 3211 }
3917 3212
3918 edges[edge].dy = abs (outline->outline[i + 2] 3213 bot = (outline->outline[bottom].y - outline->ymin);
3919 - outline->outline[next_vertex + 2]); 3214 edges[edge].top = (outline->outline[top].y - outline->ymin);
3215
3216 /* Record the edge. Rasterization happens from bottom to
3217 up, so record the X at the bottom. */
3218 edges[edge].x = (outline->outline[bottom].x - outline->xmin);
3219 dx = (outline->outline[top].x - outline->outline[bottom].x);
3220 dy = abs (outline->outline[top].y
3221 - outline->outline[bottom].y);
3920 3222
3921 /* Compute the increment. This is which direction X moves in 3223 /* Compute the increment. This is which direction X moves in
3922 for each increase in Y. */ 3224 for each increase in Y. */
3923 3225
3924 if (edges[edge].dx >= 0) 3226 if (dx >= 0)
3925 edges[edge].inc_x = 1; 3227 inc_x = 1;
3926 else 3228 else
3927 { 3229 {
3928 edges[edge].inc_x = -1; 3230 inc_x = -1;
3929 edges[edge].dx = -edges[edge].dx; 3231 dx = -dx;
3930 } 3232 }
3931 3233
3932 /* Compute the step X. This is how much X changes for each 3234 /* Compute the step X. This is how much X changes for each
3933 increase in Y. */ 3235 increase in Y. */
3934 edges[edge].step_x = (edges[edge].inc_x 3236 edges[edge].step_x = inc_x * sfnt_div_fixed (dx, dy);
3935 * sfnt_div_fixed (edges[edge].dx,
3936 edges[edge].dy));
3937 3237
3938 /* Step to first grid point. */ 3238 /* Step to first grid point. */
3939 y = sfnt_poly_grid_ceil (edges[edge].bottom); 3239 y = sfnt_poly_grid_ceil (bot);
3940 sfnt_step_edge_by (&edges[edge], edges[edge].bottom - y); 3240 sfnt_step_edge_by (&edges[edge], bot - y);
3941 edges[edge].bottom = y; 3241 edges[edge].bottom = y;
3942 edges[edge].next = NULL; 3242 edges[edge].next = NULL;
3943 3243
@@ -4219,7 +3519,7 @@ sfnt_raster_edge (struct sfnt_edge *edges, size_t num_edges,
4219/* Generate an alpha mask for the glyph outline OUTLINE. Value is the 3519/* Generate an alpha mask for the glyph outline OUTLINE. Value is the
4220 alpha mask upon success, NULL upon failure. */ 3520 alpha mask upon success, NULL upon failure. */
4221 3521
4222static struct sfnt_raster * 3522TEST_STATIC struct sfnt_raster *
4223sfnt_raster_glyph_outline (struct sfnt_glyph_outline *outline) 3523sfnt_raster_glyph_outline (struct sfnt_glyph_outline *outline)
4224{ 3524{
4225 struct sfnt_raster raster, *data; 3525 struct sfnt_raster raster, *data;
@@ -4245,35 +3545,6 @@ sfnt_raster_glyph_outline (struct sfnt_glyph_outline *outline)
4245 3545
4246/* Glyph metrics computation. */ 3546/* Glyph metrics computation. */
4247 3547
4248struct sfnt_long_hor_metric
4249{
4250 uint16_t advance_width;
4251 int16_t left_side_bearing;
4252};
4253
4254struct sfnt_hmtx_table
4255{
4256 /* Array of horizontal metrics for each glyph. */
4257 struct sfnt_long_hor_metric *h_metrics;
4258
4259 /* Lbearing for remaining glyphs. */
4260 int16_t *left_side_bearing;
4261};
4262
4263/* Structure describing the metrics of a single glyph. The fields
4264 mean the same as in XCharStruct, except they are 16.16 fixed point
4265 values, and are missing significant information. */
4266
4267struct sfnt_glyph_metrics
4268{
4269 /* Distance between origin and left edge of raster. Positive
4270 changes move rightwards. */
4271 sfnt_fixed lbearing;
4272
4273 /* Advance to next glyph's origin. */
4274 sfnt_fixed advance;
4275};
4276
4277/* Read an hmtx table from the font FD, using the table directory 3548/* Read an hmtx table from the font FD, using the table directory
4278 specified as SUBTABLE, the maxp table MAXP, and the hhea table 3549 specified as SUBTABLE, the maxp table MAXP, and the hhea table
4279 HHEA. 3550 HHEA.
@@ -4284,7 +3555,7 @@ struct sfnt_glyph_metrics
4284 HHEA->num_of_long_hor_metrics determines the number of left-side 3555 HHEA->num_of_long_hor_metrics determines the number of left-side
4285 bearings present. */ 3556 bearings present. */
4286 3557
4287static struct sfnt_hmtx_table * 3558TEST_STATIC struct sfnt_hmtx_table *
4288sfnt_read_hmtx_table (int fd, struct sfnt_offset_subtable *subtable, 3559sfnt_read_hmtx_table (int fd, struct sfnt_offset_subtable *subtable,
4289 struct sfnt_hhea_table *hhea, 3560 struct sfnt_hhea_table *hhea,
4290 struct sfnt_maxp_table *maxp) 3561 struct sfnt_maxp_table *maxp)
@@ -4344,8 +3615,8 @@ sfnt_read_hmtx_table (int fd, struct sfnt_offset_subtable *subtable,
4344 sfnt_swap16 (&hmtx->h_metrics[i].left_side_bearing); 3615 sfnt_swap16 (&hmtx->h_metrics[i].left_side_bearing);
4345 } 3616 }
4346 3617
4347 for (; i <= maxp->num_glyphs; ++i) 3618 for (; i < maxp->num_glyphs; ++i)
4348 sfnt_swap16 (&hmtx->left_side_bearing[i]); 3619 sfnt_swap16 (&hmtx->left_side_bearing[i - hhea->num_of_long_hor_metrics]);
4349 3620
4350 /* All done. */ 3621 /* All done. */
4351 return hmtx; 3622 return hmtx;
@@ -4358,7 +3629,7 @@ sfnt_read_hmtx_table (int fd, struct sfnt_offset_subtable *subtable,
4358 HMTX, HHEA, HEAD and MAXP should be the hmtx, hhea, head, and maxp 3629 HMTX, HHEA, HEAD and MAXP should be the hmtx, hhea, head, and maxp
4359 tables of the font respectively. */ 3630 tables of the font respectively. */
4360 3631
4361static int 3632TEST_STATIC int
4362sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size, 3633sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size,
4363 struct sfnt_glyph_metrics *metrics, 3634 struct sfnt_glyph_metrics *metrics,
4364 struct sfnt_hmtx_table *hmtx, 3635 struct sfnt_hmtx_table *hmtx,
@@ -4377,7 +3648,7 @@ sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size,
4377 advance = hmtx->h_metrics[glyph].advance_width; 3648 advance = hmtx->h_metrics[glyph].advance_width;
4378 } 3649 }
4379 else if (hhea->num_of_long_hor_metrics 3650 else if (hhea->num_of_long_hor_metrics
4380 && glyph <= maxp->num_glyphs) 3651 && glyph < maxp->num_glyphs)
4381 { 3652 {
4382 /* There is a short entry in the hmtx table. */ 3653 /* There is a short entry in the hmtx table. */
4383 lbearing 3654 lbearing
@@ -4404,6 +3675,342 @@ sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size,
4404 3675
4405 3676
4406 3677
3678/* Font style parsing. */
3679
3680/* Read the name table from the given font FD, using the table
3681 directory specified as SUBTABLE. Perform validation on the offsets
3682 in the name records. Return NULL upon failure, else the name
3683 table. */
3684
3685TEST_STATIC struct sfnt_name_table *
3686sfnt_read_name_table (int fd, struct sfnt_offset_subtable *subtable)
3687{
3688 struct sfnt_table_directory *directory;
3689 struct sfnt_name_table *name;
3690 size_t required;
3691 ssize_t rc;
3692 int i;
3693
3694 /* Find the table in the directory. */
3695
3696 directory = sfnt_find_table (subtable, SFNT_TABLE_NAME);
3697
3698 if (!directory)
3699 return NULL;
3700
3701 /* Seek to the location given in the directory. */
3702 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
3703 return NULL;
3704
3705 /* Figure out the minimum that has to be read. */
3706 required = SFNT_ENDOF (struct sfnt_name_table,
3707 string_offset, uint16_t);
3708
3709 if (directory->length < required)
3710 return NULL;
3711
3712 /* Allocate enough to hold the name table and variable length
3713 data. */
3714 name = xmalloc (sizeof *name + directory->length);
3715
3716 /* Read the fixed length data. */
3717 rc = read (fd, name, required);
3718 if (rc < required)
3719 {
3720 xfree (name);
3721 return NULL;
3722 }
3723
3724 /* Swap what was read. */
3725 sfnt_swap16 (&name->format);
3726 sfnt_swap16 (&name->count);
3727 sfnt_swap16 (&name->string_offset);
3728
3729 /* Reject unsupported formats. */
3730 if (name->format)
3731 {
3732 xfree (name);
3733 return NULL;
3734 }
3735
3736 /* Set the pointer to the start of the variable length data. */
3737 name->name_records
3738 = (struct sfnt_name_record *) (name + 1);
3739
3740 /* Check there is enough for the name records. */
3741 required = directory->length - required;
3742 if (required < name->count * sizeof *name->name_records)
3743 {
3744 xfree (name);
3745 return NULL;
3746 }
3747
3748 /* Read the variable length data. First, read the name records. */
3749 rc = read (fd, name->name_records,
3750 (name->count
3751 * sizeof *name->name_records));
3752 if (rc < (name->count
3753 * sizeof *name->name_records))
3754 {
3755 xfree (name);
3756 return NULL;
3757 }
3758
3759 /* Swap each of the name records. */
3760 for (i = 0; i < name->count; ++i)
3761 {
3762 sfnt_swap16 (&name->name_records[i].platform_id);
3763 sfnt_swap16 (&name->name_records[i].platform_specific_id);
3764 sfnt_swap16 (&name->name_records[i].language_id);
3765 sfnt_swap16 (&name->name_records[i].name_id);
3766 sfnt_swap16 (&name->name_records[i].length);
3767 sfnt_swap16 (&name->name_records[i].offset);
3768 }
3769
3770 /* Now, read the name data. */
3771
3772 if (name->string_offset > directory->length)
3773 {
3774 xfree (name);
3775 return NULL;
3776 }
3777
3778 required = directory->length - name->string_offset;
3779
3780 /* It can happen that the string offset comes before the name
3781 records, and as a result exceeds the number of bytes
3782 previously allocated. Extend name if that is the case. */
3783
3784 if (required > (directory->length
3785 - (name->count
3786 * sizeof *name->name_records)))
3787 {
3788 name = xrealloc (name, (sizeof *name
3789 + (name->count
3790 * sizeof *name->name_records)
3791 + required));
3792 name->name_records = (struct sfnt_name_record *) (name + 1);
3793 }
3794
3795 /* There is enough space past name->name_records to hold REQUIRED
3796 bytes. Seek to the right offset. */
3797
3798 if (lseek (fd, directory->offset + name->string_offset,
3799 SEEK_SET) == (off_t) -1)
3800 {
3801 xfree (name);
3802 return NULL;
3803 }
3804
3805 /* Read REQURIED bytes into the string data. */
3806 name->data = (unsigned char *) (name->name_records
3807 + name->count);
3808 rc = read (fd, name->data, required);
3809 if (rc < required)
3810 {
3811 xfree (name);
3812 return NULL;
3813 }
3814
3815 /* Now validate each of the name records. */
3816 for (i = 0; i < name->count; ++i)
3817 {
3818 if (((int) name->name_records[i].offset
3819 + name->name_records[i].length) > required)
3820 {
3821 /* The name is out of bounds! */
3822 xfree (name);
3823 return NULL;
3824 }
3825 }
3826
3827 /* Return the name table. */
3828 return name;
3829}
3830
3831/* Return a pointer to the name data corresponding with CODE under the
3832 name table NAME. Return the start of the data and the name record
3833 under *RECORD upon success, and NULL otherwise. */
3834
3835TEST_STATIC unsigned char *
3836sfnt_find_name (struct sfnt_name_table *name,
3837 enum sfnt_name_identifier_code code,
3838 struct sfnt_name_record *record)
3839{
3840 int i;
3841
3842 for (i = 0; i < name->count; ++i)
3843 {
3844 if (name->name_records[i].name_id == code)
3845 {
3846 /* The offsets within have already been validated. */
3847 *record = name->name_records[i];
3848 return name->data + record->offset;
3849 }
3850 }
3851
3852 return NULL;
3853}
3854
3855/* Read the meta table from the give font FD, using the table
3856 directory specified as SUBTABLE. Perform validation on the offsets
3857 in each metadata record. Return NULL upon failure, else the meta
3858 table. */
3859
3860TEST_STATIC struct sfnt_meta_table *
3861sfnt_read_meta_table (int fd, struct sfnt_offset_subtable *subtable)
3862{
3863 struct sfnt_table_directory *directory;
3864 struct sfnt_meta_table *meta;
3865 size_t required, i, data_size, map_size, offset;
3866 ssize_t rc;
3867
3868 /* Find the table in the directory. */
3869
3870 directory = sfnt_find_table (subtable, SFNT_TABLE_META);
3871
3872 if (!directory)
3873 return NULL;
3874
3875 /* Seek to the location given in the directory. */
3876 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
3877 return NULL;
3878
3879 /* Figure out the minimum that has to be read. */
3880 required = SFNT_ENDOF (struct sfnt_meta_table,
3881 num_data_maps, uint32_t);
3882
3883 if (directory->length < required)
3884 return NULL;
3885
3886 /* Allocate enough to hold it. */
3887 meta = xmalloc (sizeof *meta);
3888
3889 /* Read the header. */
3890 rc = read (fd, meta, required);
3891 if (rc < required)
3892 {
3893 xfree (meta);
3894 return NULL;
3895 }
3896
3897 /* Swap what has been read so far. */
3898 sfnt_swap32 (&meta->version);
3899 sfnt_swap32 (&meta->flags);
3900 sfnt_swap32 (&meta->data_offset);
3901 sfnt_swap32 (&meta->num_data_maps);
3902
3903 /* Make sure the meta is supported. */
3904 if (meta->version != 1)
3905 {
3906 xfree (meta);
3907 return NULL;
3908 }
3909
3910 /* Reallocate the table to hold sizeof *meta + meta->num_data_maps
3911 times sizeof meta->data_maps + directory->length bytes. This is
3912 because it is ok for metadata to point into the data map itself,
3913 so an unswapped copy of the whole meta contents must be
3914 retained. */
3915
3916 if (INT_MULTIPLY_WRAPV (sizeof *meta->data_maps, meta->num_data_maps,
3917 &map_size)
3918 /* Do so while checking for overflow from bad sfnt files. */
3919 || INT_ADD_WRAPV (map_size, sizeof *meta, &data_size)
3920 || INT_ADD_WRAPV (data_size, directory->length, &data_size))
3921 {
3922 xfree (meta);
3923 return NULL;
3924 }
3925
3926 /* Do the reallocation. */
3927 meta = xrealloc (meta, data_size);
3928
3929 /* Check that the remaining data is big enough to hold the data
3930 maps. */
3931 if (directory->length - required < map_size)
3932 {
3933 xfree (meta);
3934 return NULL;
3935 }
3936
3937 /* Set pointers to data_maps and data. */
3938 meta->data_maps = (struct sfnt_meta_data_map *) (meta + 1);
3939 meta->data = (unsigned char *) (meta->data_maps
3940 + meta->num_data_maps);
3941
3942 /* Now, seek back. Read the entire table into meta->data. */
3943 if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
3944 {
3945 xfree (meta);
3946 return NULL;
3947 }
3948
3949 rc = read (fd, meta->data, directory->length);
3950 if (rc < directory->length)
3951 {
3952 xfree (meta);
3953 return NULL;
3954 }
3955
3956 /* Copy the data maps into meta->data_maps and swap them one by
3957 one. */
3958 memcpy (meta->data_maps, meta->data + required,
3959 map_size);
3960
3961 for (i = 0; i < meta->num_data_maps; ++i)
3962 {
3963 sfnt_swap32 (&meta->data_maps[i].tag);
3964 sfnt_swap32 (&meta->data_maps[i].data_offset);
3965 sfnt_swap32 (&meta->data_maps[i].data_length);
3966
3967 /* Verify the data offsets. Overflow checking is particularly
3968 important here. */
3969
3970 if (INT_ADD_WRAPV (meta->data_maps[i].data_offset,
3971 meta->data_maps[i].data_length,
3972 &offset))
3973 {
3974 xfree (meta);
3975 return NULL;
3976 }
3977
3978 if (offset > directory->length)
3979 {
3980 xfree (meta);
3981 return NULL;
3982 }
3983 }
3984
3985 /* All done. */
3986 return meta;
3987}
3988
3989/* Return a pointer to the metadata corresponding to TAG under the
3990 meta table META. Return the start of the data and the metadata map
3991 under *MAP upon success, and NULL otherwise. */
3992
3993MAYBE_UNUSED TEST_STATIC char *
3994sfnt_find_metadata (struct sfnt_meta_table *meta,
3995 enum sfnt_meta_data_tag tag,
3996 struct sfnt_meta_data_map *map)
3997{
3998 int i;
3999
4000 for (i = 0; i < meta->num_data_maps; ++i)
4001 {
4002 if (meta->data_maps[i].tag == tag)
4003 {
4004 *map = meta->data_maps[i];
4005 return (char *) meta->data + map->data_offset;
4006 }
4007 }
4008
4009 return NULL;
4010}
4011
4012
4013
4407#ifdef TEST 4014#ifdef TEST
4408 4015
4409struct sfnt_test_dcontext 4016struct sfnt_test_dcontext
@@ -4508,6 +4115,13 @@ sfnt_test_span (struct sfnt_edge *edge, sfnt_fixed y,
4508} 4115}
4509 4116
4510static void 4117static void
4118sfnt_test_edge_ignore (struct sfnt_edge *edges, size_t num_edges,
4119 void *dcontext)
4120{
4121
4122}
4123
4124static void
4511sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges, 4125sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges,
4512 void *dcontext) 4126 void *dcontext)
4513{ 4127{
@@ -4593,11 +4207,15 @@ main (int argc, char **argv)
4593 sfnt_glyph code; 4207 sfnt_glyph code;
4594 struct sfnt_test_dcontext dcontext; 4208 struct sfnt_test_dcontext dcontext;
4595 struct sfnt_glyph_outline *outline; 4209 struct sfnt_glyph_outline *outline;
4596 struct timespec start, end, sub, sub1; 4210 struct timespec start, end, sub, sub1, sub2;
4597 static struct sfnt_maxp_table *maxp; 4211 static struct sfnt_maxp_table *maxp;
4598 struct sfnt_raster *raster; 4212 struct sfnt_raster *raster;
4599 struct sfnt_hmtx_table *hmtx; 4213 struct sfnt_hmtx_table *hmtx;
4600 struct sfnt_glyph_metrics metrics; 4214 struct sfnt_glyph_metrics metrics;
4215 struct sfnt_name_table *name;
4216 unsigned char *string;
4217 struct sfnt_name_record record;
4218 struct sfnt_meta_table *meta;
4601 4219
4602 if (argc != 2) 4220 if (argc != 2)
4603 return 1; 4221 return 1;
@@ -4644,6 +4262,8 @@ main (int argc, char **argv)
4644 hhea = sfnt_read_hhea_table (fd, font); 4262 hhea = sfnt_read_hhea_table (fd, font);
4645 glyf = sfnt_read_glyf_table (fd, font); 4263 glyf = sfnt_read_glyf_table (fd, font);
4646 maxp = sfnt_read_maxp_table (fd, font); 4264 maxp = sfnt_read_maxp_table (fd, font);
4265 name = sfnt_read_name_table (fd, font);
4266 meta = sfnt_read_meta_table (fd, font);
4647 hmtx = NULL; 4267 hmtx = NULL;
4648 4268
4649 if (hhea && maxp) 4269 if (hhea && maxp)
@@ -4653,6 +4273,23 @@ main (int argc, char **argv)
4653 fprintf (stderr, "maxp says num glyphs is %"PRIu16"\n", 4273 fprintf (stderr, "maxp says num glyphs is %"PRIu16"\n",
4654 maxp->num_glyphs); 4274 maxp->num_glyphs);
4655 4275
4276 if (name)
4277 {
4278 fprintf (stderr, "name table of format: %"PRIu16" count: %"
4279 PRIu16"\n", name->format, name->count);
4280
4281 string = sfnt_find_name (name, SFNT_NAME_FONT_FAMILY,
4282 &record);
4283
4284 if (string)
4285 fprintf (stderr, "FONT_FAMILY: %"PRIu16", %"PRIu16"\n",
4286 record.platform_id, record.length);
4287 }
4288
4289 if (meta)
4290 fprintf (stderr, "meta table with count: %"PRIu32"\n",
4291 meta->num_data_maps);
4292
4656 loca_long = NULL; 4293 loca_long = NULL;
4657 loca_short = NULL; 4294 loca_short = NULL;
4658 4295
@@ -4787,29 +4424,35 @@ main (int argc, char **argv)
4787 { 4424 {
4788 sfnt_test_max = outline->ymax - outline->ymin; 4425 sfnt_test_max = outline->ymax - outline->ymin;
4789 4426
4790 for (i = 0; i < outline->outline_used; i += 3) 4427 for (i = 0; i < outline->outline_used; i++)
4791 { 4428 {
4792 printf ("ctx.%s (%g, %g) /* %g, %g */\n", 4429 printf ("ctx.%s (%g, %g) /* %g, %g */\n",
4793 (outline->outline[i] & SFNT_GLYPH_OUTLINE_LINETO 4430 (outline->outline[i].flags & SFNT_GLYPH_OUTLINE_LINETO
4794 ? "lineTo" : "moveTo"), 4431 ? "lineTo" : "moveTo"),
4795 sfnt_coerce_fixed (outline->outline[i + 1] 4432 sfnt_coerce_fixed (outline->outline[i].x
4796 - outline->xmin), 4433 - outline->xmin),
4797 sfnt_coerce_fixed (sfnt_test_max 4434 sfnt_coerce_fixed (sfnt_test_max
4798 - (outline->outline[i + 2] 4435 - (outline->outline[i].y
4799 - outline->ymin)), 4436 - outline->ymin)),
4800 sfnt_coerce_fixed (outline->outline[i + 1] 4437 sfnt_coerce_fixed (outline->outline[i].x
4801 - outline->xmin), 4438 - outline->xmin),
4802 sfnt_coerce_fixed (outline->outline[i + 2] 4439 sfnt_coerce_fixed (outline->outline[i].y
4803 - outline->ymin)); 4440 - outline->ymin));
4804 } 4441 }
4805 4442
4443 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
4444 sfnt_build_outline_edges (outline, sfnt_test_edge_ignore,
4445 NULL);
4446 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
4447 sub1 = timespec_sub (end, start);
4448
4806 sfnt_build_outline_edges (outline, sfnt_test_edge, 4449 sfnt_build_outline_edges (outline, sfnt_test_edge,
4807 NULL); 4450 NULL);
4808 4451
4809 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start); 4452 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
4810 raster = sfnt_raster_glyph_outline (outline); 4453 raster = sfnt_raster_glyph_outline (outline);
4811 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end); 4454 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
4812 sub1 = timespec_sub (end, start); 4455 sub2 = timespec_sub (end, start);
4813 4456
4814 /* Print out the raster. */ 4457 /* Print out the raster. */
4815 sfnt_test_raster (raster); 4458 sfnt_test_raster (raster);
@@ -4836,8 +4479,10 @@ main (int argc, char **argv)
4836 4479
4837 printf ("time spent outlining: %lld sec %ld nsec\n", 4480 printf ("time spent outlining: %lld sec %ld nsec\n",
4838 (long long) sub.tv_sec, sub.tv_nsec); 4481 (long long) sub.tv_sec, sub.tv_nsec);
4839 printf ("time spent rasterizing: %lld sec %ld nsec\n", 4482 printf ("time spent building edges: %lld sec %ld nsec\n",
4840 (long long) sub1.tv_sec, sub1.tv_nsec); 4483 (long long) sub1.tv_sec, sub1.tv_nsec);
4484 printf ("time spent rasterizing: %lld sec %ld nsec\n",
4485 (long long) sub2.tv_sec, sub2.tv_nsec);
4841 4486
4842 xfree (outline); 4487 xfree (outline);
4843 } 4488 }
@@ -4861,6 +4506,8 @@ main (int argc, char **argv)
4861 xfree (glyf); 4506 xfree (glyf);
4862 xfree (maxp); 4507 xfree (maxp);
4863 xfree (hmtx); 4508 xfree (hmtx);
4509 xfree (name);
4510 xfree (meta);
4864 4511
4865 return 0; 4512 return 0;
4866} 4513}
diff --git a/src/xdisp.c b/src/xdisp.c
index 3e4e4c7bc3b..96402fac56c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -15230,6 +15230,15 @@ redisplay_tool_bar (struct frame *f)
15230 /* Always do that now. */ 15230 /* Always do that now. */
15231 clear_glyph_matrix (w->desired_matrix); 15231 clear_glyph_matrix (w->desired_matrix);
15232 f->fonts_changed = true; 15232 f->fonts_changed = true;
15233
15234 /* Kludge (this applies to the X Windows version as well as
15235 Android): when the tool bar size changes,
15236 adjust_window_size (presumably called by
15237 change_tool_bar_height_hook) does not call through to
15238 resize_frame_windows. Pending further investigation,
15239 just call it here as well. */
15240 resize_frame_windows (f, FRAME_INNER_HEIGHT (f), false);
15241
15233 return true; 15242 return true;
15234 } 15243 }
15235 } 15244 }