Mercurial > emacs
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 (¤t, 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 |