diff options
| author | Karoly Lorentey | 2005-10-09 20:00:17 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2005-10-09 20:00:17 +0000 |
| commit | 0ff21b4e57b1dc7c714c21c9eea1a4906630ecf2 (patch) | |
| tree | 3e8596405b243531128cd0f1d8f59d2ab9e7f7c7 /src/macterm.c | |
| parent | a3c07f683d1f9fbf7c7af0120dfebc5fc34b61fa (diff) | |
| parent | 20ef86730cca82a1a2e212a665c0b119ed2d70b2 (diff) | |
| download | emacs-0ff21b4e57b1dc7c714c21c9eea1a4906630ecf2.tar.gz emacs-0ff21b4e57b1dc7c714c21c9eea1a4906630ecf2.zip | |
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
Diffstat (limited to 'src/macterm.c')
| -rw-r--r-- | src/macterm.c | 818 |
1 files changed, 652 insertions, 166 deletions
diff --git a/src/macterm.c b/src/macterm.c index f727c013809..c9d91607573 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -658,6 +658,79 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height) | |||
| 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) |
| @@ -682,6 +755,89 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | |||
| 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); |
| @@ -689,6 +845,9 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, 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))); |
| @@ -1549,6 +1708,61 @@ x_per_char_metric (font, char2b) | |||
| 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) |
| @@ -1600,6 +1814,9 @@ x_per_char_metric (font, char2b) | |||
| 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)) |
| @@ -1925,6 +2142,35 @@ mac_compute_glyph_string_overhangs (s) | |||
| 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); |
| @@ -1946,6 +2192,9 @@ mac_compute_glyph_string_overhangs (s) | |||
| 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; |
| @@ -2003,7 +2252,7 @@ x_draw_glyph_string_background (s, force_p) | |||
| 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 |
| @@ -2057,11 +2306,15 @@ x_draw_glyph_string_foreground (s) | |||
| 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 |
| @@ -2072,14 +2325,18 @@ x_draw_glyph_string_foreground (s) | |||
| 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) |
| @@ -3246,9 +3503,57 @@ 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; |
| @@ -3260,24 +3565,49 @@ XTflash (f) | |||
| 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; |
| 3573 | struct timeval timeout; | ||
| 3267 | 3574 | ||
| 3268 | EMACS_GET_TIME (timeout); | 3575 | EMACS_GET_TIME (current); |
| 3269 | 3576 | ||
| 3270 | /* In effect, timeout = wakeup - timeout. | 3577 | /* Break if result would be negative. */ |
| 3271 | Break if result would be negative. */ | 3578 | if (timeval_subtract (¤t, wakeup, current)) |
| 3272 | if (timeval_subtract (&timeout, wakeup, timeout)) | 3579 | break; |
| 3273 | 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 | } |
| @@ -6277,7 +6607,7 @@ 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 |
| @@ -6295,7 +6625,7 @@ xlfdpat_block_match_1 (blk, string, start_max) | |||
| 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'. */ |
| @@ -6431,6 +6761,10 @@ 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; |
| @@ -6630,6 +6964,74 @@ init_font_name_table () | |||
| 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) |
| @@ -6642,8 +7044,6 @@ init_font_name_table () | |||
| 6642 | return; | 7044 | return; |
| 6643 | } | 7045 | } |
| 6644 | 7046 | ||
| 6645 | text_encoding_info_alist = create_text_encoding_info_alist (); | ||
| 6646 | |||
| 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) |
| @@ -6683,28 +7083,29 @@ init_font_name_table () | |||
| 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 | { |
| 7089 | char *cs = SDATA (XCAR (rest)); | ||
| 6689 | 7090 | ||
| 6690 | if (size == 0) | 7091 | if (size == 0) |
| 6691 | { | 7092 | { |
| 6692 | add_font_name_table_entry (mac_to_x_fontname (name, size, | 7093 | add_font_name_table_entry (mac_to_x_fontname (name, size, |
| 6693 | style, cs)); | 7094 | style, cs)); |
| 6694 | add_font_name_table_entry (mac_to_x_fontname (name, size, | 7095 | add_font_name_table_entry (mac_to_x_fontname (name, size, |
| 6695 | italic, cs)); | 7096 | italic, cs)); |
| 6696 | add_font_name_table_entry (mac_to_x_fontname (name, size, | 7097 | add_font_name_table_entry (mac_to_x_fontname (name, size, |
| 6697 | bold, cs)); | 7098 | bold, cs)); |
| 6698 | add_font_name_table_entry (mac_to_x_fontname (name, size, | 7099 | add_font_name_table_entry (mac_to_x_fontname (name, size, |
| 6699 | italic | bold, | 7100 | italic | bold, |
| 6700 | cs)); | 7101 | cs)); |
| 6701 | } | 7102 | } |
| 6702 | else | 7103 | else |
| 6703 | { | 7104 | { |
| 6704 | add_font_name_table_entry (mac_to_x_fontname (name, size, | 7105 | add_font_name_table_entry (mac_to_x_fontname (name, size, |
| 6705 | style, cs)); | 7106 | style, cs)); |
| 6706 | } | 7107 | } |
| 6707 | } | 7108 | } |
| 6708 | } | 7109 | } |
| 6709 | } | 7110 | } |
| 6710 | 7111 | ||
| @@ -7139,6 +7540,9 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 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; |
| @@ -7190,6 +7594,48 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 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); |
| @@ -7203,6 +7649,9 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 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 | ||
| @@ -7210,6 +7659,9 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 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" |
| @@ -7220,6 +7672,91 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 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 || |
| @@ -7234,24 +7771,26 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 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) | ||
| 7239 | font->max_byte1 = 1; | ||
| 7240 | else | ||
| 7241 | font->max_byte1 = 0; | ||
| 7242 | font->min_char_or_byte2 = 0x20; | ||
| 7243 | font->max_char_or_byte2 = 0xff; | ||
| 7244 | |||
| 7245 | if (is_two_byte_font) | 7774 | if (is_two_byte_font) |
| 7246 | { | 7775 | { |
| 7776 | font->min_byte1 = 0xa1; | ||
| 7777 | font->max_byte1 = 0xfe; | ||
| 7778 | font->min_char_or_byte2 = 0xa1; | ||
| 7779 | font->max_char_or_byte2 = 0xfe; | ||
| 7780 | |||
| 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: |
| @@ -7263,9 +7802,15 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 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 | { |
| @@ -7284,55 +7829,56 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 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 | } |
| @@ -7346,6 +7892,10 @@ mac_unload_font (dpyinfo, font) | |||
| 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 | ||
| @@ -10188,75 +10738,6 @@ init_quit_char_handler () | |||
| 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 |
| @@ -10435,6 +10916,11 @@ syms_of_macterm () | |||
| 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 |