comparison src/macterm.c @ 83383:2a679c81f552

Merged from miles@gnu.org--gnu-2005 (patch 118-132, 551-577) Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-551 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-552 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-553 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-554 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-555 Remove CVS keywords from newsticker files * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-556 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-557 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-558 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-559 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-560 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-561 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-562 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-563 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-564 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-565 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-566 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-567 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-568 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-569 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-570 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-571 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-572 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-573 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-574 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-575 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-576 Update from CVS * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-577 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-118 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-119 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-120 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-121 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-122 Update from CVS: lisp/mm-url.el (mm-url-decode-entities): Fix regexp. * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-123 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-124 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-125 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-126 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-127 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-128 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-129 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-130 Update from CVS * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-131 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2005/gnus--rel--5.10--patch-132 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-423
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 09 Oct 2005 20:00:17 +0000
parents 46dfd959d88a 00a8cdae2968
children 08b4dd6a6e87
comparison
equal deleted inserted replaced
83382:7a3090aca393 83383:2a679c81f552
656 SetGWorld (old_port, old_gdh); 656 SetGWorld (old_port, old_gdh);
657 } 657 }
658 #endif 658 #endif
659 659
660 660
661 #if USE_ATSUI
662 static OSStatus
663 atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
664 ConstUniCharArrayPtr text;
665 UniCharCount text_length;
666 ATSUStyle style;
667 ATSUTextLayout *text_layout;
668 {
669 OSStatus err;
670 static ATSUTextLayout saved_text_layout = NULL; /* not reentrant */
671
672 if (saved_text_layout == NULL)
673 {
674 UniCharCount lengths[] = {kATSUToTextEnd};
675 ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag};
676 ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)};
677 static ATSLineLayoutOptions line_layout =
678 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
679 kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics
680 #else
681 kATSLineIsDisplayOnly
682 #endif
683 ;
684 ATSUAttributeValuePtr values[] = {&line_layout};
685
686 err = ATSUCreateTextLayoutWithTextPtr (text,
687 kATSUFromTextBeginning,
688 kATSUToTextEnd,
689 text_length,
690 1, lengths, &style,
691 &saved_text_layout);
692 if (err == noErr)
693 err = ATSUSetLayoutControls (saved_text_layout,
694 sizeof (tags) / sizeof (tags[0]),
695 tags, sizes, values);
696 /* XXX: Should we do this? */
697 if (err == noErr)
698 err = ATSUSetTransientFontMatching (saved_text_layout, true);
699 }
700 else
701 {
702 err = ATSUSetRunStyle (saved_text_layout, style,
703 kATSUFromTextBeginning, kATSUToTextEnd);
704 if (err == noErr)
705 err = ATSUSetTextPointerLocation (saved_text_layout, text,
706 kATSUFromTextBeginning,
707 kATSUToTextEnd,
708 text_length);
709 }
710
711 if (err == noErr)
712 *text_layout = saved_text_layout;
713 return err;
714 }
715 #endif
716
717 static void
718 mac_invert_rectangle (display, w, x, y, width, height)
719 Display *display;
720 WindowPtr w;
721 int x, y;
722 unsigned int width, height;
723 {
724 Rect r;
725
726 SetPortWindowPort (w);
727
728 SetRect (&r, x, y, x + width, y + height);
729
730 InvertRect (&r);
731 }
732
733
661 static void 734 static void
662 mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, 735 mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode,
663 bytes_per_char) 736 bytes_per_char)
664 Display *display; 737 Display *display;
665 WindowPtr w; 738 WindowPtr w;
680 753
681 RGBForeColor (GC_FORE_COLOR (gc)); 754 RGBForeColor (GC_FORE_COLOR (gc));
682 if (mode != srcOr) 755 if (mode != srcOr)
683 RGBBackColor (GC_BACK_COLOR (gc)); 756 RGBBackColor (GC_BACK_COLOR (gc));
684 757
758 #if USE_ATSUI
759 if (GC_FONT (gc)->mac_style)
760 {
761 OSErr err;
762 ATSUTextLayout text_layout;
763
764 xassert (bytes_per_char == 2);
765
766 #ifndef WORDS_BIG_ENDIAN
767 {
768 int i;
769 Unichar *text = (Unichar *)buf;
770
771 for (i = 0; i < nchars; i++)
772 text[i] = buf[2*i] << 8 | buf[2*i+1];
773 }
774 #endif
775 err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
776 nchars,
777 GC_FONT (gc)->mac_style,
778 &text_layout);
779 if (err == noErr)
780 {
781 #ifdef MAC_OSX
782 if (NILP (Vmac_use_core_graphics))
783 {
784 #endif
785 MoveTo (x, y);
786 ATSUDrawText (text_layout,
787 kATSUFromTextBeginning, kATSUToTextEnd,
788 kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
789 #ifdef MAC_OSX
790 }
791 else
792 {
793 CGrafPtr port;
794 CGContextRef context;
795 Rect rect;
796 RgnHandle region = NewRgn ();
797 float port_height;
798 ATSUAttributeTag tags[] = {kATSUCGContextTag};
799 ByteCount sizes[] = {sizeof (CGContextRef)};
800 ATSUAttributeValuePtr values[] = {&context};
801
802 GetPort (&port);
803 QDBeginCGContext (port, &context);
804 GetPortBounds (port, &rect);
805 port_height = rect.bottom - rect.top;
806 GetClip (region);
807 GetRegionBounds (region, &rect);
808 /* XXX: This is not correct if the clip region is not a
809 simple rectangle. */
810 CGContextClipToRect (context,
811 CGRectMake (rect.left,
812 port_height - rect.bottom,
813 rect.right - rect.left,
814 rect.bottom - rect.top));
815 DisposeRgn (region);
816 CGContextSetRGBFillColor
817 (context,
818 RED_FROM_ULONG (gc->xgcv.foreground) / 255.0,
819 GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0,
820 BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0,
821 1.0);
822 err = ATSUSetLayoutControls (text_layout,
823 sizeof (tags) / sizeof (tags[0]),
824 tags, sizes, values);
825 if (err == noErr)
826 ATSUDrawText (text_layout,
827 kATSUFromTextBeginning, kATSUToTextEnd,
828 Long2Fix (x), Long2Fix (port_height - y));
829 ATSUClearLayoutControls (text_layout,
830 sizeof (tags) / sizeof (tags[0]),
831 tags);
832 CGContextSynchronize (context);
833 QDEndCGContext (port, &context);
834 }
835 #endif
836 }
837 }
838 else
839 {
840 #endif
685 TextFont (GC_FONT (gc)->mac_fontnum); 841 TextFont (GC_FONT (gc)->mac_fontnum);
686 TextSize (GC_FONT (gc)->mac_fontsize); 842 TextSize (GC_FONT (gc)->mac_fontsize);
687 TextFace (GC_FONT (gc)->mac_fontface); 843 TextFace (GC_FONT (gc)->mac_fontface);
688 TextMode (mode); 844 TextMode (mode);
689 845
690 MoveTo (x, y); 846 MoveTo (x, y);
691 DrawText (buf, 0, nchars * bytes_per_char); 847 DrawText (buf, 0, nchars * bytes_per_char);
848 #if USE_ATSUI
849 }
850 #endif
692 851
693 if (mode != srcOr) 852 if (mode != srcOr)
694 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); 853 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w)));
695 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 854 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
696 if (!NILP(Vmac_use_core_graphics)) 855 if (!NILP(Vmac_use_core_graphics))
1547 /* The result metric information. */ 1706 /* The result metric information. */
1548 XCharStruct *pcm = NULL; 1707 XCharStruct *pcm = NULL;
1549 1708
1550 xassert (font && char2b); 1709 xassert (font && char2b);
1551 1710
1711 #if USE_ATSUI
1712 if (font->mac_style)
1713 {
1714 if (char2b->byte1 >= font->min_byte1
1715 && char2b->byte1 <= font->max_byte1
1716 && char2b->byte2 >= font->min_char_or_byte2
1717 && char2b->byte2 <= font->max_char_or_byte2)
1718 {
1719 pcm = (font->per_char
1720 + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1)
1721 * (char2b->byte1 - font->min_byte1))
1722 + (char2b->byte2 - font->min_char_or_byte2));
1723 }
1724
1725 if (pcm && !pcm->valid_p)
1726 {
1727 OSErr err;
1728 ATSUTextLayout text_layout;
1729 UniChar c;
1730 int char_width;
1731 ATSTrapezoid glyph_bounds;
1732 Rect char_bounds;
1733
1734 c = (char2b->byte1 << 8) + char2b->byte2;
1735 BLOCK_INPUT;
1736 err = atsu_get_text_layout_with_text_ptr (&c, 1,
1737 font->mac_style,
1738 &text_layout);
1739 if (err == noErr)
1740 err = ATSUMeasureTextImage (text_layout,
1741 kATSUFromTextBeginning, kATSUToTextEnd,
1742 0, 0, &char_bounds);
1743
1744 if (err == noErr)
1745 err = ATSUGetGlyphBounds (text_layout, 0, 0,
1746 kATSUFromTextBeginning, kATSUToTextEnd,
1747 kATSUseFractionalOrigins, 1,
1748 &glyph_bounds, NULL);
1749 UNBLOCK_INPUT;
1750 if (err != noErr)
1751 pcm = NULL;
1752 else
1753 {
1754 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
1755 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
1756
1757 char_width = Fix2Long (glyph_bounds.upperRight.x
1758 - glyph_bounds.upperLeft.x);
1759 STORE_XCHARSTRUCT (*pcm, char_width, char_bounds);
1760 }
1761 }
1762 }
1763 else
1764 {
1765 #endif
1552 if (font->per_char != NULL) 1766 if (font->per_char != NULL)
1553 { 1767 {
1554 if (font->min_byte1 == 0 && font->max_byte1 == 0) 1768 if (font->min_byte1 == 0 && font->max_byte1 == 0)
1555 { 1769 {
1556 /* min_char_or_byte2 specifies the linear character index 1770 /* min_char_or_byte2 specifies the linear character index
1598 information, as given by both min_bounds and max_bounds. */ 1812 information, as given by both min_bounds and max_bounds. */
1599 if (char2b->byte2 >= font->min_char_or_byte2 1813 if (char2b->byte2 >= font->min_char_or_byte2
1600 && char2b->byte2 <= font->max_char_or_byte2) 1814 && char2b->byte2 <= font->max_char_or_byte2)
1601 pcm = &font->max_bounds; 1815 pcm = &font->max_bounds;
1602 } 1816 }
1817 #if USE_ATSUI
1818 }
1819 #endif
1603 1820
1604 return ((pcm == NULL 1821 return ((pcm == NULL
1605 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)) 1822 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
1606 ? NULL : pcm); 1823 ? NULL : pcm);
1607 } 1824 }
1923 && s->first_glyph->type == CHAR_GLYPH) 2140 && s->first_glyph->type == CHAR_GLYPH)
1924 { 2141 {
1925 Rect r; 2142 Rect r;
1926 MacFontStruct *font = s->font; 2143 MacFontStruct *font = s->font;
1927 2144
2145 #if USE_ATSUI
2146 if (font->mac_style)
2147 {
2148 OSErr err;
2149 ATSUTextLayout text_layout;
2150 UniChar *buf;
2151 int i;
2152
2153 SetRect (&r, 0, 0, 0, 0);
2154 buf = xmalloc (sizeof (UniChar) * s->nchars);
2155 if (buf)
2156 {
2157 for (i = 0; i < s->nchars; i++)
2158 buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2;
2159
2160 err = atsu_get_text_layout_with_text_ptr (buf, s->nchars,
2161 font->mac_style,
2162 &text_layout);
2163 if (err == noErr)
2164 err = ATSUMeasureTextImage (text_layout,
2165 kATSUFromTextBeginning,
2166 kATSUToTextEnd,
2167 0, 0, &r);
2168 xfree (buf);
2169 }
2170 }
2171 else
2172 {
2173 #endif
1928 TextFont (font->mac_fontnum); 2174 TextFont (font->mac_fontnum);
1929 TextSize (font->mac_fontsize); 2175 TextSize (font->mac_fontsize);
1930 TextFace (font->mac_fontface); 2176 TextFace (font->mac_fontface);
1931 2177
1932 if (s->two_byte_p) 2178 if (s->two_byte_p)
1944 buf[i] = s->char2b[i].byte2; 2190 buf[i] = s->char2b[i].byte2;
1945 QDTextBounds (s->nchars, buf, &r); 2191 QDTextBounds (s->nchars, buf, &r);
1946 xfree (buf); 2192 xfree (buf);
1947 } 2193 }
1948 } 2194 }
2195 #if USE_ATSUI
2196 }
2197 #endif
1949 2198
1950 s->right_overhang = r.right > s->width ? r.right - s->width : 0; 2199 s->right_overhang = r.right > s->width ? r.right - s->width : 0;
1951 s->left_overhang = r.left < 0 ? -r.left : 0; 2200 s->left_overhang = r.left < 0 ? -r.left : 0;
1952 } 2201 }
1953 } 2202 }
2001 XSetFillStyle (s->display, s->gc, FillSolid); 2250 XSetFillStyle (s->display, s->gc, FillSolid);
2002 s->background_filled_p = 1; 2251 s->background_filled_p = 1;
2003 } 2252 }
2004 else 2253 else
2005 #endif 2254 #endif
2006 #ifdef MAC_OS8 2255 #if defined (MAC_OS8) && !USE_ATSUI
2007 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width 2256 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
2008 || s->font_not_found_p 2257 || s->font_not_found_p
2009 || s->extends_to_end_of_line_p 2258 || s->extends_to_end_of_line_p
2010 || force_p) 2259 || force_p)
2011 #endif 2260 #endif
2055 2304
2056 if (s->font_info->vertical_centering) 2305 if (s->font_info->vertical_centering)
2057 boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff; 2306 boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
2058 2307
2059 /* If we can use 8-bit functions, condense S->char2b. */ 2308 /* If we can use 8-bit functions, condense S->char2b. */
2060 if (!s->two_byte_p) 2309 if (!s->two_byte_p
2310 #if USE_ATSUI
2311 && GC_FONT (s->gc)->mac_style == NULL
2312 #endif
2313 )
2061 for (i = 0; i < s->nchars; ++i) 2314 for (i = 0; i < s->nchars; ++i)
2062 char1b[i] = s->char2b[i].byte2; 2315 char1b[i] = s->char2b[i].byte2;
2063 2316
2064 #ifdef MAC_OS8 2317 #if defined (MAC_OS8) && !USE_ATSUI
2065 /* Draw text with XDrawString if background has already been 2318 /* Draw text with XDrawString if background has already been
2066 filled. Otherwise, use XDrawImageString. (Note that 2319 filled. Otherwise, use XDrawImageString. (Note that
2067 XDrawImageString is usually faster than XDrawString.) Always 2320 XDrawImageString is usually faster than XDrawString.) Always
2068 use XDrawImageString when drawing the cursor so that there is 2321 use XDrawImageString when drawing the cursor so that there is
2069 no chance that characters under a box cursor are invisible. */ 2322 no chance that characters under a box cursor are invisible. */
2070 if (s->for_overlaps_p 2323 if (s->for_overlaps_p
2071 || (s->background_filled_p && s->hl != DRAW_CURSOR)) 2324 || (s->background_filled_p && s->hl != DRAW_CURSOR))
2072 #endif 2325 #endif
2073 { 2326 {
2074 /* Draw characters with 16-bit or 8-bit functions. */ 2327 /* Draw characters with 16-bit or 8-bit functions. */
2075 if (s->two_byte_p) 2328 if (s->two_byte_p
2329 #if USE_ATSUI
2330 || GC_FONT (s->gc)->mac_style
2331 #endif
2332 )
2076 XDrawString16 (s->display, s->window, s->gc, x, 2333 XDrawString16 (s->display, s->window, s->gc, x,
2077 s->ybase - boff, s->char2b, s->nchars); 2334 s->ybase - boff, s->char2b, s->nchars);
2078 else 2335 else
2079 XDrawString (s->display, s->window, s->gc, x, 2336 XDrawString (s->display, s->window, s->gc, x,
2080 s->ybase - boff, char1b, s->nchars); 2337 s->ybase - boff, char1b, s->nchars);
2081 } 2338 }
2082 #ifdef MAC_OS8 2339 #if defined (MAC_OS8) && !USE_ATSUI
2083 else 2340 else
2084 { 2341 {
2085 if (s->two_byte_p) 2342 if (s->two_byte_p)
2086 XDrawImageString16 (s->display, s->window, s->gc, x, 2343 XDrawImageString16 (s->display, s->window, s->gc, x,
2087 s->ybase - boff, s->char2b, s->nchars); 2344 s->ybase - boff, s->char2b, s->nchars);
3244 3501
3245 void 3502 void
3246 XTflash (f) 3503 XTflash (f)
3247 struct frame *f; 3504 struct frame *f;
3248 { 3505 {
3506 /* Get the height not including a menu bar widget. */
3507 int height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
3508 /* Height of each line to flash. */
3509 int flash_height = FRAME_LINE_HEIGHT (f);
3510 /* These will be the left and right margins of the rectangles. */
3511 int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
3512 int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
3513
3514 int width;
3515
3516 /* Don't flash the area between a scroll bar and the frame
3517 edge it is next to. */
3518 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f))
3519 {
3520 case vertical_scroll_bar_left:
3521 flash_left += VERTICAL_SCROLL_BAR_WIDTH_TRIM;
3522 break;
3523
3524 case vertical_scroll_bar_right:
3525 flash_right -= VERTICAL_SCROLL_BAR_WIDTH_TRIM;
3526 break;
3527
3528 default:
3529 break;
3530 }
3531
3532 width = flash_right - flash_left;
3533
3249 BLOCK_INPUT; 3534 BLOCK_INPUT;
3250 3535
3251 FlashMenuBar (0); 3536 /* If window is tall, flash top and bottom line. */
3537 if (height > 3 * FRAME_LINE_HEIGHT (f))
3538 {
3539 mac_invert_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
3540 flash_left,
3541 (FRAME_INTERNAL_BORDER_WIDTH (f)
3542 + FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f)),
3543 width, flash_height);
3544 mac_invert_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
3545 flash_left,
3546 (height - flash_height
3547 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3548 width, flash_height);
3549 }
3550 else
3551 /* If it is short, flash it all. */
3552 mac_invert_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
3553 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
3554 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
3555
3556 x_flush (f);
3252 3557
3253 { 3558 {
3254 struct timeval wakeup; 3559 struct timeval wakeup;
3255 3560
3256 EMACS_GET_TIME (wakeup); 3561 EMACS_GET_TIME (wakeup);
3258 /* Compute time to wait until, propagating carry from usecs. */ 3563 /* Compute time to wait until, propagating carry from usecs. */
3259 wakeup.tv_usec += 150000; 3564 wakeup.tv_usec += 150000;
3260 wakeup.tv_sec += (wakeup.tv_usec / 1000000); 3565 wakeup.tv_sec += (wakeup.tv_usec / 1000000);
3261 wakeup.tv_usec %= 1000000; 3566 wakeup.tv_usec %= 1000000;
3262 3567
3263 /* Keep waiting until past the time wakeup. */ 3568 /* Keep waiting until past the time wakeup or any input gets
3264 while (1) 3569 available. */
3570 while (! detect_input_pending ())
3265 { 3571 {
3266 struct timeval timeout; 3572 struct timeval current;
3267 3573 struct timeval timeout;
3268 EMACS_GET_TIME (timeout); 3574
3269 3575 EMACS_GET_TIME (current);
3270 /* In effect, timeout = wakeup - timeout. 3576
3271 Break if result would be negative. */ 3577 /* Break if result would be negative. */
3272 if (timeval_subtract (&timeout, wakeup, timeout)) 3578 if (timeval_subtract (&current, wakeup, current))
3273 break; 3579 break;
3274 3580
3275 /* Try to wait that long--but we might wake up sooner. */ 3581 /* How long `select' should wait. */
3276 select (0, NULL, NULL, NULL, &timeout); 3582 timeout.tv_sec = 0;
3583 timeout.tv_usec = 10000;
3584
3585 /* Try to wait that long--but we might wake up sooner. */
3586 select (0, NULL, NULL, NULL, &timeout);
3277 } 3587 }
3278 } 3588 }
3279 3589
3280 FlashMenuBar (0); 3590 /* If window is tall, flash top and bottom line. */
3591 if (height > 3 * FRAME_LINE_HEIGHT (f))
3592 {
3593 mac_invert_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
3594 flash_left,
3595 (FRAME_INTERNAL_BORDER_WIDTH (f)
3596 + FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f)),
3597 width, flash_height);
3598 mac_invert_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
3599 flash_left,
3600 (height - flash_height
3601 - FRAME_INTERNAL_BORDER_WIDTH (f)),
3602 width, flash_height);
3603 }
3604 else
3605 /* If it is short, flash it all. */
3606 mac_invert_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
3607 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
3608 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
3609
3610 x_flush (f);
3281 3611
3282 UNBLOCK_INPUT; 3612 UNBLOCK_INPUT;
3283 } 3613 }
3284 3614
3285 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */ 3615 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
6275 6605
6276 static INLINE int 6606 static INLINE int
6277 xlfdpat_exact_p (pat) 6607 xlfdpat_exact_p (pat)
6278 struct xlfdpat *pat; 6608 struct xlfdpat *pat;
6279 { 6609 {
6280 return (pat)->blocks == NULL; 6610 return pat->blocks == NULL;
6281 } 6611 }
6282 6612
6283 /* Return the first string in STRING + 0, ..., STRING + START_MAX such 6613 /* Return the first string in STRING + 0, ..., STRING + START_MAX such
6284 that the pattern in *BLK matches with its prefix. Return NULL 6614 that the pattern in *BLK matches with its prefix. Return NULL
6285 there is no such strings. STRING must be lowered in advance. */ 6615 there is no such strings. STRING must be lowered in advance. */
6293 int start, infinity; 6623 int start, infinity;
6294 unsigned char *p, *s; 6624 unsigned char *p, *s;
6295 6625
6296 xassert (blk->len > 0); 6626 xassert (blk->len > 0);
6297 xassert (start_max + blk->len <= strlen (string)); 6627 xassert (start_max + blk->len <= strlen (string));
6298 xassert (blk->pattern[blk->len - 1] != '?'); 6628 xassert (blk->last_char != '?');
6299 6629
6300 /* See the comments in the function `boyer_moore' (search.c) for the 6630 /* See the comments in the function `boyer_moore' (search.c) for the
6301 use of `infinity'. */ 6631 use of `infinity'. */
6302 infinity = start_max + blk->len + 1; 6632 infinity = start_max + blk->len + 1;
6303 blk->skip[blk->last_char] = infinity; 6633 blk->skip[blk->last_char] = infinity;
6429 /* the global font name table */ 6759 /* the global font name table */
6430 static char **font_name_table = NULL; 6760 static char **font_name_table = NULL;
6431 static int font_name_table_size = 0; 6761 static int font_name_table_size = 0;
6432 static int font_name_count = 0; 6762 static int font_name_count = 0;
6433 6763
6764 #if USE_ATSUI
6765 static Lisp_Object atsu_font_id_hash;
6766 #endif
6767
6434 /* Alist linking character set strings to Mac text encoding and Emacs 6768 /* Alist linking character set strings to Mac text encoding and Emacs
6435 coding system. */ 6769 coding system. */
6436 static Lisp_Object Vmac_charset_info_alist; 6770 static Lisp_Object Vmac_charset_info_alist;
6437 6771
6438 static Lisp_Object 6772 static Lisp_Object
6628 FMFontFamilyInstanceIterator ffii; 6962 FMFontFamilyInstanceIterator ffii;
6629 FMFontFamily ff; 6963 FMFontFamily ff;
6630 Lisp_Object text_encoding_info_alist; 6964 Lisp_Object text_encoding_info_alist;
6631 struct gcpro gcpro1; 6965 struct gcpro gcpro1;
6632 6966
6967 text_encoding_info_alist = create_text_encoding_info_alist ();
6968
6969 #if USE_ATSUI
6970 if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode),
6971 text_encoding_info_alist)))
6972 {
6973 OSErr err;
6974 ItemCount nfonts, i;
6975 ATSUFontID *font_ids = NULL;
6976 Ptr name, prev_name = NULL;
6977 ByteCount name_len;
6978
6979 atsu_font_id_hash =
6980 make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
6981 make_float (DEFAULT_REHASH_SIZE),
6982 make_float (DEFAULT_REHASH_THRESHOLD),
6983 Qnil, Qnil, Qnil);;
6984 err = ATSUFontCount (&nfonts);
6985 if (err == noErr)
6986 font_ids = xmalloc (sizeof (ATSUFontID) * nfonts);
6987 if (font_ids)
6988 err = ATSUGetFontIDs (font_ids, nfonts, NULL);
6989 if (err == noErr)
6990 for (i = 0; i < nfonts; i++)
6991 {
6992 err = ATSUFindFontName (font_ids[i], kFontFamilyName,
6993 kFontMacintoshPlatform, kFontNoScript,
6994 kFontNoLanguage, 0, NULL, &name_len, NULL);
6995 if (err != noErr)
6996 continue;
6997 name = xmalloc (name_len + 1);
6998 if (name == NULL)
6999 continue;
7000 name[name_len] = '\0';
7001 err = ATSUFindFontName (font_ids[i], kFontFamilyName,
7002 kFontMacintoshPlatform, kFontNoScript,
7003 kFontNoLanguage, name_len, name,
7004 NULL, NULL);
7005 if (err == noErr
7006 && *name != '.'
7007 && (prev_name == NULL
7008 || strcmp (name, prev_name) != 0))
7009 {
7010 static char *cs = "iso10646-1";
7011
7012 add_font_name_table_entry (mac_to_x_fontname (name, 0,
7013 normal, cs));
7014 add_font_name_table_entry (mac_to_x_fontname (name, 0,
7015 italic, cs));
7016 add_font_name_table_entry (mac_to_x_fontname (name, 0,
7017 bold, cs));
7018 add_font_name_table_entry (mac_to_x_fontname (name, 0,
7019 italic | bold, cs));
7020 Fputhash (Fdowncase (make_unibyte_string (name, name_len)),
7021 long_to_cons (font_ids[i]), atsu_font_id_hash);
7022 xfree (prev_name);
7023 prev_name = name;
7024 }
7025 else
7026 xfree (name);
7027 }
7028 if (prev_name)
7029 xfree (prev_name);
7030 if (font_ids)
7031 xfree (font_ids);
7032 }
7033 #endif
7034
6633 /* Create a dummy instance iterator here to avoid creating and 7035 /* Create a dummy instance iterator here to avoid creating and
6634 destroying it in the loop. */ 7036 destroying it in the loop. */
6635 if (FMCreateFontFamilyInstanceIterator (0, &ffii) != noErr) 7037 if (FMCreateFontFamilyInstanceIterator (0, &ffii) != noErr)
6636 return; 7038 return;
6637 /* Create an iterator to enumerate the font families. */ 7039 /* Create an iterator to enumerate the font families. */
6639 != noErr) 7041 != noErr)
6640 { 7042 {
6641 FMDisposeFontFamilyInstanceIterator (&ffii); 7043 FMDisposeFontFamilyInstanceIterator (&ffii);
6642 return; 7044 return;
6643 } 7045 }
6644
6645 text_encoding_info_alist = create_text_encoding_info_alist ();
6646 7046
6647 GCPRO1 (text_encoding_info_alist); 7047 GCPRO1 (text_encoding_info_alist);
6648 7048
6649 while (FMGetNextFontFamily (&ffi, &ff) == noErr) 7049 while (FMGetNextFontFamily (&ffi, &ff) == noErr)
6650 { 7050 {
6681 while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size) 7081 while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
6682 == noErr) 7082 == noErr)
6683 { 7083 {
6684 Lisp_Object rest = XCDR (XCDR (text_encoding_info)); 7084 Lisp_Object rest = XCDR (XCDR (text_encoding_info));
6685 7085
6686 for (; !NILP (rest); rest = XCDR (rest)) 7086 if (size > 0 || style == normal)
6687 { 7087 for (; !NILP (rest); rest = XCDR (rest))
6688 char *cs = SDATA (XCAR (rest)); 7088 {
6689 7089 char *cs = SDATA (XCAR (rest));
6690 if (size == 0) 7090
6691 { 7091 if (size == 0)
6692 add_font_name_table_entry (mac_to_x_fontname (name, size, 7092 {
6693 style, cs)); 7093 add_font_name_table_entry (mac_to_x_fontname (name, size,
6694 add_font_name_table_entry (mac_to_x_fontname (name, size, 7094 style, cs));
6695 italic, cs)); 7095 add_font_name_table_entry (mac_to_x_fontname (name, size,
6696 add_font_name_table_entry (mac_to_x_fontname (name, size, 7096 italic, cs));
6697 bold, cs)); 7097 add_font_name_table_entry (mac_to_x_fontname (name, size,
6698 add_font_name_table_entry (mac_to_x_fontname (name, size, 7098 bold, cs));
6699 italic | bold, 7099 add_font_name_table_entry (mac_to_x_fontname (name, size,
6700 cs)); 7100 italic | bold,
6701 } 7101 cs));
6702 else 7102 }
6703 { 7103 else
6704 add_font_name_table_entry (mac_to_x_fontname (name, size, 7104 {
6705 style, cs)); 7105 add_font_name_table_entry (mac_to_x_fontname (name, size,
6706 } 7106 style, cs));
6707 } 7107 }
7108 }
6708 } 7109 }
6709 } 7110 }
6710 7111
6711 UNGCPRO; 7112 UNGCPRO;
6712 7113
7137 SInt16 old_fontnum, old_fontsize; 7538 SInt16 old_fontnum, old_fontsize;
7138 Style old_fontface; 7539 Style old_fontface;
7139 Str255 mfontname, mfontname_decoded; 7540 Str255 mfontname, mfontname_decoded;
7140 Str31 charset; 7541 Str31 charset;
7141 SInt16 fontnum; 7542 SInt16 fontnum;
7543 #if USE_ATSUI
7544 ATSUStyle mac_style = NULL;
7545 #endif
7142 Style fontface; 7546 Style fontface;
7143 #if TARGET_API_MAC_CARBON 7547 #if TARGET_API_MAC_CARBON
7144 TextEncoding encoding; 7548 TextEncoding encoding;
7145 int scriptcode; 7549 int scriptcode;
7146 #else 7550 #else
7188 if (size == 0) 7592 if (size == 0)
7189 size = kDefaultFontSize; 7593 size = kDefaultFontSize;
7190 7594
7191 x_font_name_to_mac_font_name (name, mfontname, mfontname_decoded, 7595 x_font_name_to_mac_font_name (name, mfontname, mfontname_decoded,
7192 &fontface, charset); 7596 &fontface, charset);
7597 #if USE_ATSUI
7598 if (strcmp (charset, "iso10646-1") == 0) /* XXX */
7599 {
7600 OSErr err;
7601 ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag,
7602 kATSUQDBoldfaceTag, kATSUQDItalicTag};
7603 ByteCount sizes[] = {sizeof (ATSUFontID), sizeof (Fixed),
7604 sizeof (Boolean), sizeof (Boolean)};
7605 static ATSUFontID font_id;
7606 static Fixed size_fixed;
7607 static Boolean bold_p, italic_p;
7608 ATSUAttributeValuePtr values[] = {&font_id, &size_fixed,
7609 &bold_p, &italic_p};
7610 ATSUFontFeatureType types[] = {kAllTypographicFeaturesType};
7611 ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector};
7612 Lisp_Object font_id_cons;
7613
7614 font_id_cons = Fgethash (Fdowncase
7615 (make_unibyte_string (mfontname,
7616 strlen (mfontname))),
7617 atsu_font_id_hash, Qnil);
7618 if (NILP (font_id_cons))
7619 return NULL;
7620 font_id = cons_to_long (font_id_cons);
7621 size_fixed = Long2Fix (size);
7622 bold_p = (fontface & bold) != 0;
7623 italic_p = (fontface & italic) != 0;
7624 err = ATSUCreateStyle (&mac_style);
7625 if (err != noErr)
7626 return NULL;
7627 err = ATSUSetFontFeatures (mac_style, sizeof (types) / sizeof (types[0]),
7628 types, selectors);
7629 if (err != noErr)
7630 return NULL;
7631 err = ATSUSetAttributes (mac_style, sizeof (tags) / sizeof (tags[0]),
7632 tags, sizes, values);
7633 fontnum = -1;
7634 scriptcode = kTextEncodingMacUnicode;
7635 }
7636 else
7637 {
7638 #endif
7193 c2pstr (mfontname); 7639 c2pstr (mfontname);
7194 #if TARGET_API_MAC_CARBON 7640 #if TARGET_API_MAC_CARBON
7195 fontnum = FMGetFontFamilyFromName (mfontname); 7641 fontnum = FMGetFontFamilyFromName (mfontname);
7196 if (fontnum == kInvalidFontFamily 7642 if (fontnum == kInvalidFontFamily
7197 || FMGetFontFamilyTextEncoding (fontnum, &encoding) != noErr) 7643 || FMGetFontFamilyTextEncoding (fontnum, &encoding) != noErr)
7201 GetFNum (mfontname, &fontnum); 7647 GetFNum (mfontname, &fontnum);
7202 if (fontnum == 0) 7648 if (fontnum == 0)
7203 return NULL; 7649 return NULL;
7204 scriptcode = FontToScript (fontnum); 7650 scriptcode = FontToScript (fontnum);
7205 #endif 7651 #endif
7652 #if USE_ATSUI
7653 }
7654 #endif
7206 7655
7207 font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct)); 7656 font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct));
7208 7657
7209 font->mac_fontnum = fontnum; 7658 font->mac_fontnum = fontnum;
7210 font->mac_fontsize = size; 7659 font->mac_fontsize = size;
7211 font->mac_fontface = fontface; 7660 font->mac_fontface = fontface;
7212 font->mac_scriptcode = scriptcode; 7661 font->mac_scriptcode = scriptcode;
7662 #if USE_ATSUI
7663 font->mac_style = mac_style;
7664 #endif
7213 7665
7214 /* Apple Japanese (SJIS) font is listed as both 7666 /* Apple Japanese (SJIS) font is listed as both
7215 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0" 7667 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
7216 (Roman script) in init_font_name_table (). The latter should be 7668 (Roman script) in init_font_name_table (). The latter should be
7217 treated as a one-byte font. */ 7669 treated as a one-byte font. */
7218 if (scriptcode == smJapanese && strcmp (charset, "jisx0201.1976-0") == 0) 7670 if (scriptcode == smJapanese && strcmp (charset, "jisx0201.1976-0") == 0)
7219 font->mac_scriptcode = smRoman; 7671 font->mac_scriptcode = smRoman;
7220 7672
7221 font->full_name = mac_to_x_fontname (mfontname_decoded, size, fontface, charset); 7673 font->full_name = mac_to_x_fontname (mfontname_decoded, size, fontface, charset);
7222 7674
7675 #if USE_ATSUI
7676 if (font->mac_style)
7677 {
7678 OSErr err;
7679 ATSUTextLayout text_layout;
7680 UniChar c = 0x20;
7681 Rect char_bounds, min_bounds, max_bounds;
7682 int min_width, max_width;
7683 ATSTrapezoid glyph_bounds;
7684
7685 font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000);
7686 if (font->per_char == NULL)
7687 {
7688 mac_unload_font (&one_mac_display_info, font);
7689 return NULL;
7690 }
7691 bzero (font->per_char, sizeof (XCharStruct) * 0x10000);
7692
7693 err = atsu_get_text_layout_with_text_ptr (&c, 1,
7694 font->mac_style,
7695 &text_layout);
7696 if (err != noErr)
7697 {
7698 mac_unload_font (&one_mac_display_info, font);
7699 return NULL;
7700 }
7701
7702 for (c = 0x20; c <= 0x7e; c++)
7703 {
7704 err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning);
7705 if (err == noErr)
7706 err = ATSUMeasureTextImage (text_layout,
7707 kATSUFromTextBeginning, kATSUToTextEnd,
7708 0, 0, &char_bounds);
7709 if (err == noErr)
7710 err = ATSUGetGlyphBounds (text_layout, 0, 0,
7711 kATSUFromTextBeginning, kATSUToTextEnd,
7712 kATSUseFractionalOrigins, 1,
7713 &glyph_bounds, NULL);
7714 if (err == noErr)
7715 {
7716 xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x
7717 == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x);
7718
7719 char_width = Fix2Long (glyph_bounds.upperRight.x
7720 - glyph_bounds.upperLeft.x);
7721 STORE_XCHARSTRUCT (font->per_char[c],
7722 char_width, char_bounds);
7723 if (c == 0x20)
7724 {
7725 min_width = max_width = char_width;
7726 min_bounds = max_bounds = char_bounds;
7727 font->ascent = -Fix2Long (glyph_bounds.upperLeft.y);
7728 font->descent = Fix2Long (glyph_bounds.lowerLeft.y);
7729 }
7730 else
7731 {
7732 if (char_width > 0)
7733 {
7734 min_width = min (min_width, char_width);
7735 max_width = max (max_width, char_width);
7736 }
7737 if (!EmptyRect (&char_bounds))
7738 {
7739 SetRect (&min_bounds,
7740 max (min_bounds.left, char_bounds.left),
7741 max (min_bounds.top, char_bounds.top),
7742 min (min_bounds.right, char_bounds.right),
7743 min (min_bounds.bottom, char_bounds.bottom));
7744 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7745 }
7746 }
7747 }
7748 }
7749 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7750 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7751
7752 font->min_byte1 = 0;
7753 font->max_byte1 = 0xff;
7754 font->min_char_or_byte2 = 0;
7755 font->max_char_or_byte2 = 0xff;
7756 }
7757 else
7758 {
7759 #endif
7223 is_two_byte_font = font->mac_scriptcode == smJapanese || 7760 is_two_byte_font = font->mac_scriptcode == smJapanese ||
7224 font->mac_scriptcode == smTradChinese || 7761 font->mac_scriptcode == smTradChinese ||
7225 font->mac_scriptcode == smSimpChinese || 7762 font->mac_scriptcode == smSimpChinese ||
7226 font->mac_scriptcode == smKorean; 7763 font->mac_scriptcode == smKorean;
7227 7764
7232 GetFontInfo (&the_fontinfo); 7769 GetFontInfo (&the_fontinfo);
7233 7770
7234 font->ascent = the_fontinfo.ascent; 7771 font->ascent = the_fontinfo.ascent;
7235 font->descent = the_fontinfo.descent; 7772 font->descent = the_fontinfo.descent;
7236 7773
7237 font->min_byte1 = 0;
7238 if (is_two_byte_font) 7774 if (is_two_byte_font)
7239 font->max_byte1 = 1; 7775 {
7240 else 7776 font->min_byte1 = 0xa1;
7241 font->max_byte1 = 0; 7777 font->max_byte1 = 0xfe;
7242 font->min_char_or_byte2 = 0x20; 7778 font->min_char_or_byte2 = 0xa1;
7243 font->max_char_or_byte2 = 0xff; 7779 font->max_char_or_byte2 = 0xfe;
7244 7780
7245 if (is_two_byte_font)
7246 {
7247 /* Use the width of an "ideographic space" of that font because 7781 /* Use the width of an "ideographic space" of that font because
7248 the_fontinfo.widMax returns the wrong width for some fonts. */ 7782 the_fontinfo.widMax returns the wrong width for some fonts. */
7249 switch (font->mac_scriptcode) 7783 switch (font->mac_scriptcode)
7250 { 7784 {
7251 case smJapanese: 7785 case smJapanese:
7786 font->min_byte1 = 0x81;
7787 font->max_byte1 = 0xfc;
7788 font->min_char_or_byte2 = 0x40;
7789 font->max_char_or_byte2 = 0xfc;
7252 char_width = StringWidth("\p\x81\x40"); 7790 char_width = StringWidth("\p\x81\x40");
7253 break; 7791 break;
7254 case smTradChinese: 7792 case smTradChinese:
7793 font->min_char_or_byte2 = 0x40;
7255 char_width = StringWidth("\p\xa1\x40"); 7794 char_width = StringWidth("\p\xa1\x40");
7256 break; 7795 break;
7257 case smSimpChinese: 7796 case smSimpChinese:
7258 char_width = StringWidth("\p\xa1\xa1"); 7797 char_width = StringWidth("\p\xa1\xa1");
7259 break; 7798 break;
7261 char_width = StringWidth("\p\xa1\xa1"); 7800 char_width = StringWidth("\p\xa1\xa1");
7262 break; 7801 break;
7263 } 7802 }
7264 } 7803 }
7265 else 7804 else
7266 /* Do this instead of use the_fontinfo.widMax, which incorrectly 7805 {
7267 returns 15 for 12-point Monaco! */ 7806 font->min_byte1 = font->max_byte1 = 0;
7268 char_width = CharWidth ('m'); 7807 font->min_char_or_byte2 = 0x20;
7808 font->max_char_or_byte2 = 0xff;
7809
7810 /* Do this instead of use the_fontinfo.widMax, which incorrectly
7811 returns 15 for 12-point Monaco! */
7812 char_width = CharWidth ('m');
7813 }
7269 7814
7270 if (is_two_byte_font) 7815 if (is_two_byte_font)
7271 { 7816 {
7272 font->per_char = NULL; 7817 font->per_char = NULL;
7273 7818
7282 7827
7283 font->min_bounds = font->max_bounds; 7828 font->min_bounds = font->max_bounds;
7284 } 7829 }
7285 else 7830 else
7286 { 7831 {
7287 font->per_char = (XCharStruct *) 7832 int c, min_width, max_width;
7288 xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); 7833 Rect char_bounds, min_bounds, max_bounds;
7289 { 7834 char ch;
7290 int c, min_width, max_width; 7835
7291 Rect char_bounds, min_bounds, max_bounds; 7836 font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
7292 char ch; 7837
7293 7838 min_width = max_width = char_width;
7294 min_width = max_width = char_width; 7839 SetRect (&min_bounds, -32767, -32767, 32767, 32767);
7295 SetRect (&min_bounds, -32767, -32767, 32767, 32767); 7840 SetRect (&max_bounds, 0, 0, 0, 0);
7296 SetRect (&max_bounds, 0, 0, 0, 0); 7841 for (c = 0x20; c <= 0xff; c++)
7297 for (c = 0x20; c <= 0xff; c++) 7842 {
7298 { 7843 ch = c;
7299 ch = c; 7844 char_width = CharWidth (ch);
7300 char_width = CharWidth (ch); 7845 QDTextBounds (1, &ch, &char_bounds);
7301 QDTextBounds (1, &ch, &char_bounds); 7846 STORE_XCHARSTRUCT (font->per_char[c - 0x20],
7302 STORE_XCHARSTRUCT (font->per_char[c - 0x20], 7847 char_width, char_bounds);
7303 char_width, char_bounds); 7848 /* Some Japanese fonts (in SJIS encoding) return 0 as the
7304 /* Some Japanese fonts (in SJIS encoding) return 0 as the 7849 character width of 0x7f. */
7305 character width of 0x7f. */ 7850 if (char_width > 0)
7306 if (char_width > 0) 7851 {
7307 { 7852 min_width = min (min_width, char_width);
7308 min_width = min (min_width, char_width); 7853 max_width = max (max_width, char_width);
7309 max_width = max (max_width, char_width); 7854 }
7310 } 7855 if (!EmptyRect (&char_bounds))
7311 if (!EmptyRect (&char_bounds)) 7856 {
7312 { 7857 SetRect (&min_bounds,
7313 SetRect (&min_bounds, 7858 max (min_bounds.left, char_bounds.left),
7314 max (min_bounds.left, char_bounds.left), 7859 max (min_bounds.top, char_bounds.top),
7315 max (min_bounds.top, char_bounds.top), 7860 min (min_bounds.right, char_bounds.right),
7316 min (min_bounds.right, char_bounds.right), 7861 min (min_bounds.bottom, char_bounds.bottom));
7317 min (min_bounds.bottom, char_bounds.bottom)); 7862 UnionRect (&max_bounds, &char_bounds, &max_bounds);
7318 UnionRect (&max_bounds, &char_bounds, &max_bounds); 7863 }
7319 } 7864 }
7320 } 7865 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
7321 STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); 7866 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
7322 STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); 7867 if (min_width == max_width
7323 if (min_width == max_width 7868 && max_bounds.left >= 0 && max_bounds.right <= max_width)
7324 && max_bounds.left >= 0 && max_bounds.right <= max_width) 7869 {
7325 { 7870 /* Fixed width and no overhangs. */
7326 /* Fixed width and no overhangs. */ 7871 xfree (font->per_char);
7327 xfree (font->per_char); 7872 font->per_char = NULL;
7328 font->per_char = NULL; 7873 }
7329 }
7330 }
7331 } 7874 }
7332 7875
7333 TextFont (old_fontnum); /* restore previous font number, size and face */ 7876 TextFont (old_fontnum); /* restore previous font number, size and face */
7334 TextSize (old_fontsize); 7877 TextSize (old_fontsize);
7335 TextFace (old_fontface); 7878 TextFace (old_fontface);
7879 #if USE_ATSUI
7880 }
7881 #endif
7336 7882
7337 return font; 7883 return font;
7338 } 7884 }
7339 7885
7340 7886
7344 XFontStruct *font; 7890 XFontStruct *font;
7345 { 7891 {
7346 xfree (font->full_name); 7892 xfree (font->full_name);
7347 if (font->per_char) 7893 if (font->per_char)
7348 xfree (font->per_char); 7894 xfree (font->per_char);
7895 #if USE_ATSUI
7896 if (font->mac_style)
7897 ATSUDisposeStyle (font->mac_style);
7898 #endif
7349 xfree (font); 7899 xfree (font);
7350 } 7900 }
7351 7901
7352 7902
7353 /* Load font named FONTNAME of the size SIZE for frame F, and return a 7903 /* Load font named FONTNAME of the size SIZE for frame F, and return a
10186 /* Look at <architecture/adb_kb_map.h> for details */ 10736 /* Look at <architecture/adb_kb_map.h> for details */
10187 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/ 10737 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
10188 10738
10189 mac_determine_quit_char_modifiers(); 10739 mac_determine_quit_char_modifiers();
10190 } 10740 }
10191
10192 static Boolean
10193 quit_char_comp (EventRef inEvent, void *inCompData)
10194 {
10195 if (GetEventClass(inEvent) != kEventClassKeyboard)
10196 return false;
10197 if (GetEventKind(inEvent) != kEventRawKeyDown)
10198 return false;
10199 {
10200 UInt32 keyCode;
10201 UInt32 keyModifiers;
10202 GetEventParameter(inEvent, kEventParamKeyCode,
10203 typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
10204 if (keyCode != mac_quit_char_keycode)
10205 return false;
10206 GetEventParameter(inEvent, kEventParamKeyModifiers,
10207 typeUInt32, NULL, sizeof(UInt32), NULL, &keyModifiers);
10208 if (keyModifiers != mac_quit_char_modifiers)
10209 return false;
10210 }
10211 return true;
10212 }
10213
10214 void
10215 mac_check_for_quit_char ()
10216 {
10217 EventRef event;
10218 static EMACS_TIME last_check_time = { 0, 0 };
10219 static EMACS_TIME one_second = { 1, 0 };
10220 EMACS_TIME now, t;
10221
10222 /* If windows are not initialized, return immediately (keep it bouncin'). */
10223 if (!mac_quit_char_modifiers)
10224 return;
10225
10226 /* Don't check if last check is less than a second ago. */
10227 EMACS_GET_TIME (now);
10228 EMACS_SUB_TIME (t, now, last_check_time);
10229 if (EMACS_TIME_LT (t, one_second))
10230 return;
10231 last_check_time = now;
10232
10233 /* Redetermine modifiers because they are based on lisp variables */
10234 mac_determine_quit_char_modifiers ();
10235
10236 /* Fill the queue with events */
10237 BLOCK_INPUT;
10238 ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &event);
10239 event = FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp,
10240 NULL);
10241 UNBLOCK_INPUT;
10242 if (event)
10243 {
10244 struct input_event e;
10245
10246 /* Use an input_event to emulate what the interrupt handler does. */
10247 EVENT_INIT (e);
10248 e.kind = ASCII_KEYSTROKE_EVENT;
10249 e.code = quit_char;
10250 e.arg = Qnil;
10251 e.modifiers = NULL;
10252 e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60);
10253 XSETFRAME (e.frame_or_window, mac_focus_frame (&one_mac_display_info));
10254 /* Remove event from queue to prevent looping. */
10255 RemoveEventFromQueue (GetMainEventQueue (), event);
10256 ReleaseEvent (event);
10257 kbd_buffer_store_event (&e);
10258 }
10259 }
10260 #endif /* MAC_OSX */ 10741 #endif /* MAC_OSX */
10261 10742
10262 static void 10743 static void
10263 init_menu_bar () 10744 init_menu_bar ()
10264 { 10745 {
10433 last_mouse_scroll_bar = Qnil; 10914 last_mouse_scroll_bar = Qnil;
10434 10915
10435 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); 10916 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
10436 staticpro (&Qmac_ready_for_drag_n_drop); 10917 staticpro (&Qmac_ready_for_drag_n_drop);
10437 10918
10919 #if USE_ATSUI
10920 staticpro (&atsu_font_id_hash);
10921 atsu_font_id_hash = Qnil;
10922 #endif
10923
10438 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, 10924 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
10439 doc: /* If not nil, Emacs uses toolkit scroll bars. */); 10925 doc: /* If not nil, Emacs uses toolkit scroll bars. */);
10440 #ifdef USE_TOOLKIT_SCROLL_BARS 10926 #ifdef USE_TOOLKIT_SCROLL_BARS
10441 Vx_toolkit_scroll_bars = Qt; 10927 Vx_toolkit_scroll_bars = Qt;
10442 #else 10928 #else