To: vim-dev@vim.org Subject: Patch 7.1.275 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 7.1.275 (extra) Problem: Mac: ATSUI and 'antialias' don't work properly together. Solution: Fix this and the input method. (Jjgod Jiang) Files: src/vim.h, src/gui_mac.c *** ../vim-7.1.274/src/vim.h Wed Feb 20 12:22:59 2008 --- src/vim.h Wed Mar 12 13:18:58 2008 *************** *** 461,468 **** /* * Check input method control. */ ! #if defined(FEAT_XIM) || \ ! (defined(FEAT_GUI) && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME))) # define USE_IM_CONTROL #endif --- 461,469 ---- /* * Check input method control. */ ! #if defined(FEAT_XIM) \ ! || (defined(FEAT_GUI) && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME))) \ ! || defined(FEAT_GUI_MAC) # define USE_IM_CONTROL #endif *** ../vim-7.1.274/src/gui_mac.c Sat Sep 29 13:15:29 2007 --- src/gui_mac.c Wed Mar 12 13:40:57 2008 *************** *** 59,65 **** --- 59,91 ---- #ifdef MACOS_CONVERT # define USE_CARBONKEYHANDLER + + static int im_is_active = FALSE; + #if 0 + static int im_start_row = 0; + static int im_start_col = 0; + #endif + + #define NR_ELEMS(x) (sizeof(x) / sizeof(x[0])) + + static TSMDocumentID gTSMDocument; + + static void im_on_window_switch(int active); static EventHandlerUPP keyEventHandlerUPP = NULL; + static EventHandlerUPP winEventHandlerUPP = NULL; + + static pascal OSStatus gui_mac_handle_window_activate( + EventHandlerCallRef nextHandler, EventRef theEvent, void *data); + + static pascal OSStatus gui_mac_handle_text_input( + EventHandlerCallRef nextHandler, EventRef theEvent, void *data); + + static pascal OSStatus gui_mac_update_input_area( + EventHandlerCallRef nextHandler, EventRef theEvent); + + static pascal OSStatus gui_mac_unicode_key_event( + EventHandlerCallRef nextHandler, EventRef theEvent); + #endif *************** *** 137,143 **** --- 166,176 ---- #ifdef MACOS_CONVERT # define USE_ATSUI_DRAWING + int p_macatsui_last; ATSUStyle gFontStyle; + # ifdef FEAT_MBYTE + ATSUStyle gWideFontStyle; + # endif Boolean gIsFontFallbackSet; #endif *************** *** 265,270 **** --- 298,308 ---- static WindowRef drawer = NULL; // TODO: put into gui.h #endif + #ifdef USE_ATSUI_DRAWING + static void gui_mac_set_font_attributes(GuiFont font); + static void gui_mac_dispose_atsui_style(void); + #endif + /* * ------------------------------------------------------------ * Conversion Utility *************** *** 1935,1946 **** /* Dim scrollbars */ if (whichWindow == gui.VimWindow) { ! ControlRef rootControl; ! GetRootControl(gui.VimWindow, &rootControl); ! if ((event->modifiers) & activeFlag) ! ActivateControl(rootControl); ! else ! DeactivateControl(rootControl); } /* Activate */ --- 1973,1984 ---- /* Dim scrollbars */ if (whichWindow == gui.VimWindow) { ! ControlRef rootControl; ! GetRootControl(gui.VimWindow, &rootControl); ! if ((event->modifiers) & activeFlag) ! ActivateControl(rootControl); ! else ! DeactivateControl(rootControl); } /* Activate */ *************** *** 1976,1990 **** * Handle the key */ #ifdef USE_CARBONKEYHANDLER ! static int dialog_busy = FALSE; /* TRUE when gui_mch_dialog() wants the keys */ # define INLINE_KEY_BUFFER_SIZE 80 static pascal OSStatus ! gui_mac_doKeyEventCarbon( EventHandlerCallRef nextHandler, ! EventRef theEvent, ! void *data) { /* Multibyte-friendly key event handler */ OSStatus err = -1; --- 2014,2100 ---- * Handle the key */ #ifdef USE_CARBONKEYHANDLER + static pascal OSStatus + gui_mac_handle_window_activate( + EventHandlerCallRef nextHandler, + EventRef theEvent, + void *data) + { + UInt32 eventClass = GetEventClass(theEvent); + UInt32 eventKind = GetEventKind(theEvent); + + if (eventClass == kEventClassWindow) + { + switch (eventKind) + { + case kEventWindowActivated: + #if defined(USE_IM_CONTROL) + im_on_window_switch(TRUE); + #endif + return noErr; + + case kEventWindowDeactivated: + #if defined(USE_IM_CONTROL) + im_on_window_switch(FALSE); + #endif + return noErr; + } + } + + return eventNotHandledErr; + } + + static pascal OSStatus + gui_mac_handle_text_input( + EventHandlerCallRef nextHandler, + EventRef theEvent, + void *data) + { + UInt32 eventClass = GetEventClass(theEvent); + UInt32 eventKind = GetEventKind(theEvent); + + if (eventClass != kEventClassTextInput) + return eventNotHandledErr; ! if ((kEventTextInputUpdateActiveInputArea != eventKind) && ! (kEventTextInputUnicodeForKeyEvent != eventKind) && ! (kEventTextInputOffsetToPos != eventKind) && ! (kEventTextInputPosToOffset != eventKind) && ! (kEventTextInputGetSelectedText != eventKind)) ! return eventNotHandledErr; ! ! switch (eventKind) ! { ! case kEventTextInputUpdateActiveInputArea: ! return gui_mac_update_input_area(nextHandler, theEvent); ! case kEventTextInputUnicodeForKeyEvent: ! return gui_mac_unicode_key_event(nextHandler, theEvent); ! ! case kEventTextInputOffsetToPos: ! case kEventTextInputPosToOffset: ! case kEventTextInputGetSelectedText: ! break; ! } ! ! return eventNotHandledErr; ! } ! ! static pascal ! OSStatus gui_mac_update_input_area( ! EventHandlerCallRef nextHandler, ! EventRef theEvent) ! { ! return eventNotHandledErr; ! } ! ! static int dialog_busy = FALSE; /* TRUE when gui_mch_dialog() wants the ! keys */ # define INLINE_KEY_BUFFER_SIZE 80 static pascal OSStatus ! gui_mac_unicode_key_event( EventHandlerCallRef nextHandler, ! EventRef theEvent) { /* Multibyte-friendly key event handler */ OSStatus err = -1; *************** *** 2000,2006 **** char_u *to = NULL; Boolean isSpecial = FALSE; int i; ! EventRef keyEvent; /* Mask the mouse (as per user setting) */ if (p_mh) --- 2110,2116 ---- char_u *to = NULL; Boolean isSpecial = FALSE; int i; ! EventRef keyEvent; /* Mask the mouse (as per user setting) */ if (p_mh) *************** *** 2008,2046 **** /* Don't use the keys when the dialog wants them. */ if (dialog_busy) ! return eventNotHandledErr; if (noErr != GetEventParameter(theEvent, kEventParamTextInputSendText, ! typeUnicodeText, NULL, 0, &actualSize, NULL)) ! return eventNotHandledErr; text = (UniChar *)alloc(actualSize); if (!text) ! return eventNotHandledErr; err = GetEventParameter(theEvent, kEventParamTextInputSendText, ! typeUnicodeText, NULL, actualSize, NULL, text); require_noerr(err, done); err = GetEventParameter(theEvent, kEventParamTextInputSendKeyboardEvent, ! typeEventRef, NULL, sizeof(EventRef), NULL, &keyEvent); require_noerr(err, done); err = GetEventParameter(keyEvent, kEventParamKeyModifiers, ! typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); require_noerr(err, done); err = GetEventParameter(keyEvent, kEventParamKeyCode, ! typeUInt32, NULL, sizeof(UInt32), NULL, &key_sym); require_noerr(err, done); err = GetEventParameter(keyEvent, kEventParamKeyMacCharCodes, ! typeChar, NULL, sizeof(char), NULL, &charcode); require_noerr(err, done); #ifndef USE_CMD_KEY if (modifiers & cmdKey) ! goto done; /* Let system handle Cmd+... */ #endif key_char = charcode; --- 2118,2156 ---- /* Don't use the keys when the dialog wants them. */ if (dialog_busy) ! return eventNotHandledErr; if (noErr != GetEventParameter(theEvent, kEventParamTextInputSendText, ! typeUnicodeText, NULL, 0, &actualSize, NULL)) ! return eventNotHandledErr; text = (UniChar *)alloc(actualSize); if (!text) ! return eventNotHandledErr; err = GetEventParameter(theEvent, kEventParamTextInputSendText, ! typeUnicodeText, NULL, actualSize, NULL, text); require_noerr(err, done); err = GetEventParameter(theEvent, kEventParamTextInputSendKeyboardEvent, ! typeEventRef, NULL, sizeof(EventRef), NULL, &keyEvent); require_noerr(err, done); err = GetEventParameter(keyEvent, kEventParamKeyModifiers, ! typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers); require_noerr(err, done); err = GetEventParameter(keyEvent, kEventParamKeyCode, ! typeUInt32, NULL, sizeof(UInt32), NULL, &key_sym); require_noerr(err, done); err = GetEventParameter(keyEvent, kEventParamKeyMacCharCodes, ! typeChar, NULL, sizeof(char), NULL, &charcode); require_noerr(err, done); #ifndef USE_CMD_KEY if (modifiers & cmdKey) ! goto done; /* Let system handle Cmd+... */ #endif key_char = charcode; *************** *** 2048,2131 **** /* Find the special key (eg., for cursor keys) */ if (actualSize <= sizeof(UniChar) && ! ((text[0] < 0x20) || (text[0] == 0x7f))) { ! for (i = 0; special_keys[i].key_sym != (KeySym)0; ++i) ! if (special_keys[i].key_sym == key_sym) ! { ! key_char = TO_SPECIAL(special_keys[i].vim_code0, ! special_keys[i].vim_code1); ! key_char = simplify_key(key_char, ! (int *)&vimModifiers); ! isSpecial = TRUE; ! break; ! } } /* Intercept CMD-. and CTRL-c */ if (((modifiers & controlKey) && key_char == 'c') || ! ((modifiers & cmdKey) && key_char == '.')) ! got_int = TRUE; if (!isSpecial) { ! /* remove SHIFT for keys that are already shifted, e.g., ! * '(' and '*' */ ! if (key_char < 0x100 && !isalpha(key_char) && isprint(key_char)) ! vimModifiers &= ~MOD_MASK_SHIFT; ! ! /* remove CTRL from keys that already have it */ ! if (key_char < 0x20) ! vimModifiers &= ~MOD_MASK_CTRL; ! ! /* don't process unicode characters here */ ! if (!IS_SPECIAL(key_char)) ! { ! /* Following code to simplify and consolidate vimModifiers ! * taken liberally from gui_w48.c */ ! key_char = simplify_key(key_char, (int *)&vimModifiers); ! ! /* Interpret META, include SHIFT, etc. */ ! key_char = extract_modifiers(key_char, (int *)&vimModifiers); ! if (key_char == CSI) ! key_char = K_CSI; ! ! if (IS_SPECIAL(key_char)) ! isSpecial = TRUE; ! } } if (vimModifiers) { ! result[len++] = CSI; ! result[len++] = KS_MODIFIER; ! result[len++] = vimModifiers; } if (isSpecial && IS_SPECIAL(key_char)) { ! result[len++] = CSI; ! result[len++] = K_SECOND(key_char); ! result[len++] = K_THIRD(key_char); } else { ! encLen = actualSize; ! to = mac_utf16_to_enc(text, actualSize, &encLen); ! if (to) ! { ! /* This is basically add_to_input_buf_csi() */ ! for (i = 0; i < encLen && len < (INLINE_KEY_BUFFER_SIZE-1); ++i) ! { ! result[len++] = to[i]; ! if (to[i] == CSI) ! { ! result[len++] = KS_EXTRA; ! result[len++] = (int)KE_CSI; ! } ! } ! vim_free(to); ! } } add_to_input_buf(result, len); --- 2158,2241 ---- /* Find the special key (eg., for cursor keys) */ if (actualSize <= sizeof(UniChar) && ! ((text[0] < 0x20) || (text[0] == 0x7f))) { ! for (i = 0; special_keys[i].key_sym != (KeySym)0; ++i) ! if (special_keys[i].key_sym == key_sym) ! { ! key_char = TO_SPECIAL(special_keys[i].vim_code0, ! special_keys[i].vim_code1); ! key_char = simplify_key(key_char, ! (int *)&vimModifiers); ! isSpecial = TRUE; ! break; ! } } /* Intercept CMD-. and CTRL-c */ if (((modifiers & controlKey) && key_char == 'c') || ! ((modifiers & cmdKey) && key_char == '.')) ! got_int = TRUE; if (!isSpecial) { ! /* remove SHIFT for keys that are already shifted, e.g., ! * '(' and '*' */ ! if (key_char < 0x100 && !isalpha(key_char) && isprint(key_char)) ! vimModifiers &= ~MOD_MASK_SHIFT; ! ! /* remove CTRL from keys that already have it */ ! if (key_char < 0x20) ! vimModifiers &= ~MOD_MASK_CTRL; ! ! /* don't process unicode characters here */ ! if (!IS_SPECIAL(key_char)) ! { ! /* Following code to simplify and consolidate vimModifiers ! * taken liberally from gui_w48.c */ ! key_char = simplify_key(key_char, (int *)&vimModifiers); ! ! /* Interpret META, include SHIFT, etc. */ ! key_char = extract_modifiers(key_char, (int *)&vimModifiers); ! if (key_char == CSI) ! key_char = K_CSI; ! ! if (IS_SPECIAL(key_char)) ! isSpecial = TRUE; ! } } if (vimModifiers) { ! result[len++] = CSI; ! result[len++] = KS_MODIFIER; ! result[len++] = vimModifiers; } if (isSpecial && IS_SPECIAL(key_char)) { ! result[len++] = CSI; ! result[len++] = K_SECOND(key_char); ! result[len++] = K_THIRD(key_char); } else { ! encLen = actualSize; ! to = mac_utf16_to_enc(text, actualSize, &encLen); ! if (to) ! { ! /* This is basically add_to_input_buf_csi() */ ! for (i = 0; i < encLen && len < (INLINE_KEY_BUFFER_SIZE-1); ++i) ! { ! result[len++] = to[i]; ! if (to[i] == CSI) ! { ! result[len++] = KS_EXTRA; ! result[len++] = (int)KE_CSI; ! } ! } ! vim_free(to); ! } } add_to_input_buf(result, len); *************** *** 2135,2144 **** vim_free(text); if (err == noErr) { ! /* Fake event to wake up WNE (required to get ! * key repeat working */ ! PostEvent(keyUp, 0); ! return noErr; } return eventNotHandledErr; --- 2245,2254 ---- vim_free(text); if (err == noErr) { ! /* Fake event to wake up WNE (required to get ! * key repeat working */ ! PostEvent(keyUp, 0); ! return noErr; } return eventNotHandledErr; *************** *** 2334,2340 **** /* prevent that the vim window size changes if it's activated by a click into the tab pane */ if (whichWindow == drawer) ! return; #endif switch (thePart) --- 2444,2450 ---- /* prevent that the vim window size changes if it's activated by a click into the tab pane */ if (whichWindow == drawer) ! return; #endif switch (thePart) *************** *** 2569,2579 **** if (IsShowContextualMenuClick(event)) { # if 0 ! gui_mac_handle_contextual_menu(event); # else ! gui_mac_doMouseDownEvent(event); # endif ! return; } /* Handle normal event */ --- 2679,2689 ---- if (IsShowContextualMenuClick(event)) { # if 0 ! gui_mac_handle_contextual_menu(event); # else ! gui_mac_doMouseDownEvent(event); # endif ! return; } /* Handle normal event */ *************** *** 2832,2838 **** # else /* OSErr GetApplicationBundleFSSpec(FSSpecPtr theFSSpecPtr) * of TN2015 - * This technic remove the ../Contents/MacOS/etc part */ (void)GetCurrentProcess(&psn); /* if (err != noErr) return err; */ --- 2942,2947 ---- *************** *** 2933,2942 **** /* TODO: Move most of this stuff toward gui_mch_init */ Rect windRect; MenuHandle pomme; - EventTypeSpec eventTypeSpec; EventHandlerRef mouseWheelHandlerRef; #ifdef USE_CARBONKEYHANDLER ! EventHandlerRef keyEventHandlerRef; #endif ControlRef rootControl; --- 3042,3050 ---- /* TODO: Move most of this stuff toward gui_mch_init */ Rect windRect; MenuHandle pomme; EventHandlerRef mouseWheelHandlerRef; #ifdef USE_CARBONKEYHANDLER ! EventTypeSpec eventTypeSpec; #endif ControlRef rootControl; *************** *** 3042,3057 **** } #ifdef USE_CARBONKEYHANDLER ! eventTypeSpec.eventClass = kEventClassTextInput; ! eventTypeSpec.eventKind = kEventUnicodeForKeyEvent; ! keyEventHandlerUPP = NewEventHandlerUPP(gui_mac_doKeyEventCarbon); ! if (noErr != InstallApplicationEventHandler(keyEventHandlerUPP, 1, ! &eventTypeSpec, NULL, &keyEventHandlerRef)) { - keyEventHandlerRef = NULL; DisposeEventHandlerUPP(keyEventHandlerUPP); keyEventHandlerUPP = NULL; } #endif /* --- 3150,3196 ---- } #ifdef USE_CARBONKEYHANDLER ! InterfaceTypeList supportedServices = { kUnicodeDocument }; ! NewTSMDocument(1, supportedServices, &gTSMDocument, 0); ! ! /* We don't support inline input yet, use input window by default */ ! UseInputWindow(gTSMDocument, TRUE); ! ! /* Should we activate the document by default? */ ! // ActivateTSMDocument(gTSMDocument); ! ! EventTypeSpec textEventTypes[] = { ! { kEventClassTextInput, kEventTextInputUpdateActiveInputArea }, ! { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }, ! { kEventClassTextInput, kEventTextInputPosToOffset }, ! { kEventClassTextInput, kEventTextInputOffsetToPos }, ! }; ! ! keyEventHandlerUPP = NewEventHandlerUPP(gui_mac_handle_text_input); ! if (noErr != InstallApplicationEventHandler(keyEventHandlerUPP, ! NR_ELEMS(textEventTypes), ! textEventTypes, NULL, NULL)) { DisposeEventHandlerUPP(keyEventHandlerUPP); keyEventHandlerUPP = NULL; } + + EventTypeSpec windowEventTypes[] = { + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowDeactivated }, + }; + + /* Install window event handler to support TSMDocument activate and + * deactivate */ + winEventHandlerUPP = NewEventHandlerUPP(gui_mac_handle_window_activate); + if (noErr != InstallWindowEventHandler(gui.VimWindow, + winEventHandlerUPP, + NR_ELEMS(windowEventTypes), + windowEventTypes, NULL, NULL)) + { + DisposeEventHandlerUPP(winEventHandlerUPP); + winEventHandlerUPP = NULL; + } #endif /* *************** *** 3107,3112 **** --- 3246,3264 ---- return OK; } + #ifdef USE_ATSUI_DRAWING + static void + gui_mac_dispose_atsui_style(void) + { + if (p_macatsui && gFontStyle) + ATSUDisposeStyle(gFontStyle); + #ifdef FEAT_MBYTE + if (p_macatsui && gWideFontStyle) + ATSUDisposeStyle(gWideFontStyle); + #endif + } + #endif + void gui_mch_exit(int rc) { *************** *** 3122,3129 **** DisposeEventHandlerUPP(mouseWheelHandlerUPP); #ifdef USE_ATSUI_DRAWING ! if (p_macatsui && gFontStyle) ! ATSUDisposeStyle(gFontStyle); #endif /* Exit to shell? */ --- 3274,3286 ---- DisposeEventHandlerUPP(mouseWheelHandlerUPP); #ifdef USE_ATSUI_DRAWING ! gui_mac_dispose_atsui_style(); ! #endif ! ! #ifdef USE_CARBONKEYHANDLER ! FixTSMDocument(gTSMDocument); ! DeactivateTSMDocument(gTSMDocument); ! DeleteTSMDocument(gTSMDocument); #endif /* Exit to shell? */ *************** *** 3263,3268 **** --- 3420,3445 ---- return selected_font; } + #ifdef USE_ATSUI_DRAWING + static void + gui_mac_create_atsui_style(void) + { + if (p_macatsui && gFontStyle == NULL) + { + if (ATSUCreateStyle(&gFontStyle) != noErr) + gFontStyle = NULL; + } + #ifdef FEAT_MBYTE + if (p_macatsui && gWideFontStyle == NULL) + { + if (ATSUCreateStyle(&gWideFontStyle) != noErr) + gWideFontStyle = NULL; + } + #endif + + p_macatsui_last = p_macatsui; + } + #endif /* * Initialise vim to use the font with the given name. Return FAIL if the font *************** *** 3280,3290 **** char_u used_font_name[512]; #ifdef USE_ATSUI_DRAWING ! if (p_macatsui && gFontStyle == NULL) ! { ! if (ATSUCreateStyle(&gFontStyle) != noErr) ! gFontStyle = NULL; ! } #endif if (font_name == NULL) --- 3457,3463 ---- char_u used_font_name[512]; #ifdef USE_ATSUI_DRAWING ! gui_mac_create_atsui_style(); #endif if (font_name == NULL) *************** *** 3348,3396 **** gui.char_height = font_info.ascent + font_info.descent + p_linespace; #ifdef USE_ATSUI_DRAWING - ATSUFontID fontID; - Fixed fontSize; - ATSStyleRenderingOptions fontOptions; - if (p_macatsui && gFontStyle) ! { ! fontID = font & 0xFFFF; ! fontSize = Long2Fix(font >> 16); ! ! /* No antialiasing by default (do not attempt to touch antialising ! * options on pre-Jaguar) */ ! fontOptions = ! (gMacSystemVersion >= 0x1020) ? ! kATSStyleNoAntiAliasing : ! kATSStyleNoOptions; ! ! ATSUAttributeTag attribTags[] = ! { ! kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag, ! kATSUMaxATSUITagValue+1 ! }; ! ByteCount attribSizes[] = ! { ! sizeof(ATSUFontID), sizeof(Fixed), ! sizeof(ATSStyleRenderingOptions), sizeof font ! }; ! ATSUAttributeValuePtr attribValues[] = ! { ! &fontID, &fontSize, &fontOptions, &font ! }; ! ! /* Convert font id to ATSUFontID */ ! if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr) ! { ! if (ATSUSetAttributes(gFontStyle, ! (sizeof attribTags)/sizeof(ATSUAttributeTag), ! attribTags, attribSizes, attribValues) != noErr) ! { ! ATSUDisposeStyle(gFontStyle); ! gFontStyle = NULL; ! } ! } ! } #endif return OK; --- 3521,3528 ---- gui.char_height = font_info.ascent + font_info.descent + p_linespace; #ifdef USE_ATSUI_DRAWING if (p_macatsui && gFontStyle) ! gui_mac_set_font_attributes(font); #endif return OK; *************** *** 3447,3452 **** --- 3579,3646 ---- } #endif + #ifdef USE_ATSUI_DRAWING + static void + gui_mac_set_font_attributes(GuiFont font) + { + ATSUFontID fontID; + Fixed fontSize; + Fixed fontWidth; + + fontID = font & 0xFFFF; + fontSize = Long2Fix(font >> 16); + fontWidth = Long2Fix(gui.char_width); + + ATSUAttributeTag attribTags[] = + { + kATSUFontTag, kATSUSizeTag, kATSUImposeWidthTag, + kATSUMaxATSUITagValue + 1 + }; + + ByteCount attribSizes[] = + { + sizeof(ATSUFontID), sizeof(Fixed), sizeof(fontWidth), + sizeof(font) + }; + + ATSUAttributeValuePtr attribValues[] = + { + &fontID, &fontSize, &fontWidth, &font + }; + + if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr) + { + if (ATSUSetAttributes(gFontStyle, + (sizeof attribTags) / sizeof(ATSUAttributeTag), + attribTags, attribSizes, attribValues) != noErr) + { + # ifndef NDEBUG + fprintf(stderr, "couldn't set font style\n"); + # endif + ATSUDisposeStyle(gFontStyle); + gFontStyle = NULL; + } + + #ifdef FEAT_MBYTE + if (has_mbyte) + { + /* FIXME: we should use a more mbyte sensitive way to support + * wide font drawing */ + fontWidth = Long2Fix(gui.char_width * 2); + + if (ATSUSetAttributes(gWideFontStyle, + (sizeof attribTags) / sizeof(ATSUAttributeTag), + attribTags, attribSizes, attribValues) != noErr) + { + ATSUDisposeStyle(gWideFontStyle); + gWideFontStyle = NULL; + } + } + #endif + } + } + #endif + /* * Set the current text font. */ *************** *** 3456,3518 **** #ifdef USE_ATSUI_DRAWING GuiFont currFont; ByteCount actualFontByteCount; - ATSUFontID fontID; - Fixed fontSize; - ATSStyleRenderingOptions fontOptions; if (p_macatsui && gFontStyle) { /* Avoid setting same font again */ ! if (ATSUGetAttribute(gFontStyle, kATSUMaxATSUITagValue+1, sizeof font, ! &currFont, &actualFontByteCount) == noErr && ! actualFontByteCount == (sizeof font)) { if (currFont == font) return; } ! fontID = font & 0xFFFF; ! fontSize = Long2Fix(font >> 16); ! /* Respect p_antialias setting only for wide font. ! * The reason for doing this at the moment is a bit complicated, ! * but it's mainly because a) latin (non-wide) aliased fonts ! * look bad in OS X 10.3.x and below (due to a bug in ATS), and ! * b) wide multibyte input does not suffer from that problem. */ ! /*fontOptions = ! (p_antialias && (font == gui.wide_font)) ? ! kATSStyleNoOptions : kATSStyleNoAntiAliasing; ! */ ! /*fontOptions = kATSStyleAntiAliasing;*/ ! ! ATSUAttributeTag attribTags[] = ! { ! kATSUFontTag, kATSUSizeTag, kATSUStyleRenderingOptionsTag, ! kATSUMaxATSUITagValue+1 ! }; ! ByteCount attribSizes[] = ! { ! sizeof(ATSUFontID), sizeof(Fixed), ! sizeof(ATSStyleRenderingOptions), sizeof font ! }; ! ATSUAttributeValuePtr attribValues[] = ! { ! &fontID, &fontSize, &fontOptions, &font ! }; ! ! if (FMGetFontFromFontFamilyInstance(fontID, 0, &fontID, NULL) == noErr) ! { ! if (ATSUSetAttributes(gFontStyle, ! (sizeof attribTags)/sizeof(ATSUAttributeTag), ! attribTags, attribSizes, attribValues) != noErr) ! { ! # ifndef NDEBUG ! fprintf(stderr, "couldn't set font style\n"); ! # endif ! ATSUDisposeStyle(gFontStyle); ! gFontStyle = NULL; ! } ! } ! } if (p_macatsui && !gIsFontFallbackSet) --- 3650,3668 ---- #ifdef USE_ATSUI_DRAWING GuiFont currFont; ByteCount actualFontByteCount; if (p_macatsui && gFontStyle) { /* Avoid setting same font again */ ! if (ATSUGetAttribute(gFontStyle, kATSUMaxATSUITagValue + 1, ! sizeof(font), &currFont, &actualFontByteCount) == noErr ! && actualFontByteCount == (sizeof font)) { if (currFont == font) return; } ! gui_mac_set_font_attributes(font); } if (p_macatsui && !gIsFontFallbackSet) *************** *** 3536,3542 **** &fallbackFonts, NULL) == noErr) { ! ATSUSetFontFallbacks((sizeof fallbackFonts)/sizeof(ATSUFontID), &fallbackFonts, kATSUSequentialFallbacksPreferred); } /* ATSUAttributeValuePtr fallbackValues[] = { }; --- 3686,3694 ---- &fallbackFonts, NULL) == noErr) { ! ATSUSetFontFallbacks((sizeof fallbackFonts)/sizeof(ATSUFontID), ! &fallbackFonts, ! kATSUSequentialFallbacksPreferred); } /* ATSUAttributeValuePtr fallbackValues[] = { }; *************** *** 3921,3927 **** /* - ATSUI automatically antialiases text (Someone) * - for some reason it does not work... (Jussi) */ ! /* * When antialiasing we're using srcOr mode, we have to clear the block * before drawing the text. --- 4073,4082 ---- /* - ATSUI automatically antialiases text (Someone) * - for some reason it does not work... (Jussi) */ ! #ifdef MAC_ATSUI_DEBUG ! fprintf(stderr, "row = %d, col = %d, len = %d: '%c'\n", ! row, col, len, len == 1 ? s[0] : ' '); ! #endif /* * When antialiasing we're using srcOr mode, we have to clear the block * before drawing the text. *************** *** 3956,3990 **** } { - /* Use old-style, non-antialiased QuickDraw text rendering. */ TextMode(srcCopy); TextFace(normal); ! /* SelectFont(hdc, gui.currFont); */ ! if (flags & DRAW_TRANSP) { TextMode(srcOr); } MoveTo(TEXT_X(col), TEXT_Y(row)); - ATSUTextLayout textLayout; ! if (ATSUCreateTextLayoutWithTextPtr(tofree, ! kATSUFromTextBeginning, kATSUToTextEnd, ! utf16_len, ! (gFontStyle ? 1 : 0), &utf16_len, ! (gFontStyle ? &gFontStyle : NULL), ! &textLayout) == noErr) { ! ATSUSetTransientFontMatching(textLayout, TRUE); ! ATSUDrawText(textLayout, ! kATSUFromTextBeginning, kATSUToTextEnd, ! kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); ATSUDisposeTextLayout(textLayout); } } if (flags & DRAW_UNDERC) --- 4111,4232 ---- } { TextMode(srcCopy); TextFace(normal); ! /* SelectFont(hdc, gui.currFont); */ if (flags & DRAW_TRANSP) { TextMode(srcOr); } MoveTo(TEXT_X(col), TEXT_Y(row)); ! if (gFontStyle && flags & DRAW_BOLD) { ! Boolean attValue = true; ! ATSUAttributeTag attribTags[] = { kATSUQDBoldfaceTag }; ! ByteCount attribSizes[] = { sizeof(Boolean) }; ! ATSUAttributeValuePtr attribValues[] = { &attValue }; ! ATSUSetAttributes(gFontStyle, 1, attribTags, attribSizes, attribValues); ! } ! ! #ifdef FEAT_MBYTE ! if (has_mbyte) ! { ! int n, width_in_cell, last_width_in_cell; ! UniCharArrayOffset offset = 0; ! UniCharCount yet_to_draw = 0; ! ATSUTextLayout textLayout; ! ATSUStyle textStyle; ! ! last_width_in_cell = 1; ! ATSUCreateTextLayout(&textLayout); ! ATSUSetTextPointerLocation(textLayout, tofree, ! kATSUFromTextBeginning, ! kATSUToTextEnd, utf16_len); ! /* ! ATSUSetRunStyle(textLayout, gFontStyle, ! kATSUFromTextBeginning, kATSUToTextEnd); */ ! ! /* Compute the length in display cells. */ ! for (n = 0; n < len; n += MB_BYTE2LEN(s[n])) ! { ! width_in_cell = (*mb_ptr2cells)(s + n); ! ! /* probably we are switching from single byte character ! * to multibyte characters (which requires more than one ! * cell to draw) */ ! if (width_in_cell != last_width_in_cell) ! { ! #ifdef MAC_ATSUI_DEBUG ! fprintf(stderr, "\tn = %2d, (%d-%d), offset = %d, yet_to_draw = %d\n", ! n, last_width_in_cell, width_in_cell, offset, yet_to_draw); ! #endif ! textStyle = last_width_in_cell > 1 ? gWideFontStyle ! : gFontStyle; ! ! ATSUSetRunStyle(textLayout, textStyle, offset, yet_to_draw); ! offset += yet_to_draw; ! yet_to_draw = 0; ! last_width_in_cell = width_in_cell; ! } + yet_to_draw++; + } + + if (yet_to_draw) + { + #ifdef MAC_ATSUI_DEBUG + fprintf(stderr, "\tn = %2d, (%d-%d), offset = %d, yet_to_draw = %d\n", + n, last_width_in_cell, width_in_cell, offset, yet_to_draw); + #endif + /* finish the rest style */ + textStyle = width_in_cell > 1 ? gWideFontStyle : gFontStyle; + ATSUSetRunStyle(textLayout, textStyle, offset, kATSUToTextEnd); + } + + ATSUSetTransientFontMatching(textLayout, TRUE); + ATSUDrawText(textLayout, + kATSUFromTextBeginning, kATSUToTextEnd, + kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); ATSUDisposeTextLayout(textLayout); } + else + #endif + { + ATSUTextLayout textLayout; + + if (ATSUCreateTextLayoutWithTextPtr(tofree, + kATSUFromTextBeginning, kATSUToTextEnd, + utf16_len, + (gFontStyle ? 1 : 0), &utf16_len, + (gFontStyle ? &gFontStyle : NULL), + &textLayout) == noErr) + { + ATSUSetTransientFontMatching(textLayout, TRUE); + + ATSUDrawText(textLayout, + kATSUFromTextBeginning, kATSUToTextEnd, + kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); + + ATSUDisposeTextLayout(textLayout); + } + } + + /* drawing is done, now reset bold to normal */ + if (gFontStyle && flags & DRAW_BOLD) + { + Boolean attValue = false; + + ATSUAttributeTag attribTags[] = { kATSUQDBoldfaceTag }; + ByteCount attribSizes[] = { sizeof(Boolean) }; + ATSUAttributeValuePtr attribValues[] = { &attValue }; + + ATSUSetAttributes(gFontStyle, 1, attribTags, attribSizes, + attribValues); + } } if (flags & DRAW_UNDERC) *************** *** 3998,4003 **** --- 4240,4252 ---- gui_mch_draw_string(int row, int col, char_u *s, int len, int flags) { #if defined(USE_ATSUI_DRAWING) + if (p_macatsui == 0 && p_macatsui_last != 0) + /* switch from macatsui to nomacatsui */ + gui_mac_dispose_atsui_style(); + else if (p_macatsui != 0 && p_macatsui_last == 0) + /* switch from nomacatsui to macatsui */ + gui_mac_create_atsui_style(); + if (p_macatsui) draw_string_ATSUI(row, col, s, len, flags); else *************** *** 4228,4239 **** */ /* TODO: reduce wtime accordinly??? */ if (wtime > -1) ! sleeppyTick = 60*wtime/1000; else sleeppyTick = 32767; if (WaitNextEventWrp(mask, &event, sleeppyTick, dragRgn)) { ! gui_mac_handle_event(&event); if (input_available()) { allow_scrollbar = FALSE; --- 4477,4489 ---- */ /* TODO: reduce wtime accordinly??? */ if (wtime > -1) ! sleeppyTick = 60 * wtime / 1000; else sleeppyTick = 32767; + if (WaitNextEventWrp(mask, &event, sleeppyTick, dragRgn)) { ! gui_mac_handle_event(&event); if (input_available()) { allow_scrollbar = FALSE; *************** *** 6031,6037 **** #endif } ! #if defined(USE_IM_CONTROL) || defined(PROTO) /* * Input Method Control functions. */ --- 6346,6352 ---- #endif } ! #if (defined(USE_IM_CONTROL) || defined(PROTO)) && defined(USE_CARBONKEYHANDLER) /* * Input Method Control functions. */ *************** *** 6042,6048 **** --- 6357,6427 ---- void im_set_position(int row, int col) { + #if 0 /* TODO: Implement me! */ + im_start_row = row; + im_start_col = col; + #endif + } + + static ScriptLanguageRecord gTSLWindow; + static ScriptLanguageRecord gTSLInsert; + static ScriptLanguageRecord gTSLDefault = { 0, 0 }; + + static Component gTSCWindow; + static Component gTSCInsert; + static Component gTSCDefault; + + static int im_initialized = 0; + + static void + im_on_window_switch(int active) + { + ScriptLanguageRecord *slptr = NULL; + OSStatus err; + + if (! gui.in_use) + return; + + if (im_initialized == 0) + { + im_initialized = 1; + + /* save default TSM component (should be U.S.) to default */ + GetDefaultInputMethodOfClass(&gTSCDefault, &gTSLDefault, + kKeyboardInputMethodClass); + } + + if (active == TRUE) + { + im_is_active = TRUE; + ActivateTSMDocument(gTSMDocument); + slptr = &gTSLWindow; + + if (slptr) + { + err = SetDefaultInputMethodOfClass(gTSCWindow, slptr, + kKeyboardInputMethodClass); + if (err == noErr) + err = SetTextServiceLanguage(slptr); + + if (err == noErr) + KeyScript(slptr->fScript | smKeyForceKeyScriptMask); + } + } + else + { + err = GetTextServiceLanguage(&gTSLWindow); + if (err == noErr) + slptr = &gTSLWindow; + + if (slptr) + GetDefaultInputMethodOfClass(&gTSCWindow, slptr, + kKeyboardInputMethodClass); + + im_is_active = FALSE; + DeactivateTSMDocument(gTSMDocument); + } } /* *************** *** 6051,6057 **** void im_set_active(int active) { ! KeyScript(active ? smKeySysScript : smKeyRoman); } /* --- 6430,6486 ---- void im_set_active(int active) { ! ScriptLanguageRecord *slptr = NULL; ! OSStatus err; ! ! if (! gui.in_use) ! return; ! ! if (im_initialized == 0) ! { ! im_initialized = 1; ! ! /* save default TSM component (should be U.S.) to default */ ! GetDefaultInputMethodOfClass(&gTSCDefault, &gTSLDefault, ! kKeyboardInputMethodClass); ! } ! ! if (active == TRUE) ! { ! im_is_active = TRUE; ! ActivateTSMDocument(gTSMDocument); ! slptr = &gTSLInsert; ! ! if (slptr) ! { ! err = SetDefaultInputMethodOfClass(gTSCInsert, slptr, ! kKeyboardInputMethodClass); ! if (err == noErr) ! err = SetTextServiceLanguage(slptr); ! ! if (err == noErr) ! KeyScript(slptr->fScript | smKeyForceKeyScriptMask); ! } ! } ! else ! { ! err = GetTextServiceLanguage(&gTSLInsert); ! if (err == noErr) ! slptr = &gTSLInsert; ! ! if (slptr) ! GetDefaultInputMethodOfClass(&gTSCInsert, slptr, ! kKeyboardInputMethodClass); ! ! /* restore to default when switch to normal mode, so than we could ! * enter commands easier */ ! SetDefaultInputMethodOfClass(gTSCDefault, &gTSLDefault, ! kKeyboardInputMethodClass); ! SetTextServiceLanguage(&gTSLDefault); ! ! im_is_active = FALSE; ! DeactivateTSMDocument(gTSMDocument); ! } } /* *************** *** 6060,6068 **** int im_get_status(void) { ! SInt32 script = GetScriptManagerVariable(smKeyScript); ! return (script != smRoman ! && script == GetScriptManagerVariable(smSysScript)) ? 1 : 0; } #endif /* defined(USE_IM_CONTROL) || defined(PROTO) */ --- 6489,6498 ---- int im_get_status(void) { ! if (! gui.in_use) ! return 0; ! ! return im_is_active; } #endif /* defined(USE_IM_CONTROL) || defined(PROTO) */ *************** *** 6118,6124 **** int numTabs = 0; for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) ! ++numTabs; return numTabs; } --- 6548,6554 ---- int numTabs = 0; for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) ! ++numTabs; return numTabs; } *************** *** 6126,6133 **** static OSStatus dbItemDataCallback(ControlRef browser, DataBrowserItemID itemID, ! DataBrowserPropertyID property /* column id */, ! DataBrowserItemDataRef itemData, Boolean changeValue) { OSStatus status = noErr; --- 6556,6563 ---- static OSStatus dbItemDataCallback(ControlRef browser, DataBrowserItemID itemID, ! DataBrowserPropertyID property /* column id */, ! DataBrowserItemDataRef itemData, Boolean changeValue) { OSStatus status = noErr; *************** *** 6170,6178 **** static void dbGetContextualMenuCallback(ControlRef browser, MenuRef *menu, ! UInt32 *helpType, CFStringRef *helpItemString, ! AEDesc *selection) { // on mac os 9: kCMHelpItemNoHelp, but it's not the same *helpType = kCMHelpItemRemoveHelp; // OS X only ;-) --- 6600,6608 ---- static void dbGetContextualMenuCallback(ControlRef browser, MenuRef *menu, ! UInt32 *helpType, CFStringRef *helpItemString, ! AEDesc *selection) { // on mac os 9: kCMHelpItemNoHelp, but it's not the same *helpType = kCMHelpItemRemoveHelp; // OS X only ;-) *************** *** 6395,6403 **** gui_mch_show_tabline(int showit) { if (showit == 0) ! CloseDrawer(drawer, true); else ! OpenDrawer(drawer, kWindowEdgeRight, true); } /* --- 6825,6833 ---- gui_mch_show_tabline(int showit) { if (showit == 0) ! CloseDrawer(drawer, true); else ! OpenDrawer(drawer, kWindowEdgeRight, true); } /* *************** *** 6425,6435 **** // adjust data browser if (tabLabels != NULL) { ! int i; ! for (i = 0; i < tabLabelsSize; ++i) ! CFRelease(tabLabels[i]); ! free(tabLabels); } tabLabels = (CFStringRef *)malloc(numTabs * sizeof(CFStringRef)); tabLabelsSize = numTabs; --- 6855,6865 ---- // adjust data browser if (tabLabels != NULL) { ! int i; ! for (i = 0; i < tabLabelsSize; ++i) ! CFRelease(tabLabels[i]); ! free(tabLabels); } tabLabels = (CFStringRef *)malloc(numTabs * sizeof(CFStringRef)); tabLabelsSize = numTabs; *************** *** 6438,6444 **** { if (tp == curtab) curtabidx = nr; ! tabLabels[nr-1] = getTabLabel(tp); } RemoveDataBrowserItems(dataBrowser, kDataBrowserNoItem, 0, NULL, --- 6868,6874 ---- { if (tp == curtab) curtabidx = nr; ! tabLabels[nr-1] = getTabLabel(tp); } RemoveDataBrowserItems(dataBrowser, kDataBrowserNoItem, 0, NULL, *** ../vim-7.1.274/src/version.c Wed Mar 12 13:45:34 2008 --- src/version.c Wed Mar 12 14:31:37 2008 *************** *** 668,669 **** --- 668,671 ---- { /* Add new patch number below this line */ + /**/ + 275, /**/ -- hundred-and-one symptoms of being an internet addict: 115. You are late picking up your kid from school and try to explain to the teacher you were stuck in Web traffic. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ download, build and distribute -- http://www.A-A-P.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///