From 2e952cd1136d5419f409ac7e98f38c57309a31f7 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Sat, 13 Aug 2011 16:17:59 +0000 Subject: [PATCH 001/167] simplify global cursor setting git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68685 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/cursor.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/gtk/cursor.cpp b/src/gtk/cursor.cpp index 525bccdb7e..615677e506 100644 --- a/src/gtk/cursor.cpp +++ b/src/gtk/cursor.cpp @@ -390,20 +390,15 @@ const wxCursor wxBusyCursor::GetBusyCursor() return wxCursor(wxCURSOR_WATCH); } -static void UpdateCursors(const wxWindowList& list, GdkDisplay*& display) +static void UpdateCursors(GdkDisplay** display) { - wxWindowList::const_iterator i = list.begin(); - for (size_t n = list.size(); n--; ++i) + wxWindowList::const_iterator i = wxTopLevelWindows.begin(); + for (size_t n = wxTopLevelWindows.size(); n--; ++i) { wxWindow* win = *i; - if (display == NULL && win->m_widget) - { - GdkWindow* w = gtk_widget_get_window(win->m_widget); - if (w) - display = gdk_drawable_get_display(w); - } - win->GTKUpdateCursor(true, false); - UpdateCursors(win->GetChildren(), display); + win->GTKUpdateCursor(); + if (display && *display == NULL && win->m_widget) + *display = gtk_widget_get_display(win->m_widget); } } @@ -414,8 +409,7 @@ void wxEndBusyCursor() g_globalCursor = gs_savedCursor; gs_savedCursor = wxNullCursor; - GdkDisplay* unused = NULL; - UpdateCursors(wxTopLevelWindows, unused); + UpdateCursors(NULL); } void wxBeginBusyCursor(const wxCursor* cursor) @@ -429,7 +423,7 @@ void wxBeginBusyCursor(const wxCursor* cursor) gs_savedCursor = g_globalCursor; g_globalCursor = *cursor; GdkDisplay* display = NULL; - UpdateCursors(wxTopLevelWindows, display); + UpdateCursors(&display); if (display) gdk_display_flush(display); } @@ -442,6 +436,5 @@ bool wxIsBusy() void wxSetCursor( const wxCursor& cursor ) { g_globalCursor = cursor; - GdkDisplay* unused = NULL; - UpdateCursors(wxTopLevelWindows, unused); + UpdateCursors(NULL); } From 35f5a520e2e918dc53baa8c65468fc12416ca219 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 14 Aug 2011 11:55:36 +0000 Subject: [PATCH 002/167] using proper cmd constant git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68688 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/cmdproc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/cmdproc.cpp b/src/common/cmdproc.cpp index 7de08c2790..f59886d0a5 100644 --- a/src/common/cmdproc.cpp +++ b/src/common/cmdproc.cpp @@ -62,8 +62,8 @@ wxCommandProcessor::wxCommandProcessor(int maxCommands) #endif // wxUSE_MENUS #if wxUSE_ACCEL - m_undoAccelerator = '\t' + wxAcceleratorEntry(wxACCEL_CTRL, 'Z').ToString(); - m_redoAccelerator = '\t' + wxAcceleratorEntry(wxACCEL_CTRL, 'Y').ToString(); + m_undoAccelerator = '\t' + wxAcceleratorEntry(wxACCEL_CMD, 'Z').ToString(); + m_redoAccelerator = '\t' + wxAcceleratorEntry(wxACCEL_CMD, 'Y').ToString(); #endif // wxUSE_ACCEL m_lastSavedCommand = From 73d1308b85df21aa1d69b74a37c4f88c53fe661f Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 14 Aug 2011 15:41:10 +0000 Subject: [PATCH 003/167] adding two missing strings (used in docview) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68691 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/stockitem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/stockitem.cpp b/src/common/stockitem.cpp index 5a897d7f78..2df465503d 100644 --- a/src/common/stockitem.cpp +++ b/src/common/stockitem.cpp @@ -177,6 +177,7 @@ wxString wxGetStockLabel(wxWindowID id, long flags) STOCKITEM(wxID_OPEN, _("&Open..."), _("Open...")); STOCKITEM(wxID_PASTE, _("&Paste"), _("Paste")); STOCKITEM(wxID_PREFERENCES, _("&Preferences"), _("Preferences")); + STOCKITEM(wxID_PREVIEW, _("&Preview..."), _("Preview...")); STOCKITEM(wxID_PRINT, _("&Print..."), _("Print...")); STOCKITEM(wxID_PROPERTIES, _("&Properties"), _("Properties")); STOCKITEM(wxID_REDO, _("&Redo"), _("Redo")); @@ -184,6 +185,7 @@ wxString wxGetStockLabel(wxWindowID id, long flags) STOCKITEM(wxID_REMOVE, _("Remove"), _("Remove")); STOCKITEM(wxID_REPLACE, _("Rep&lace"), _("Replace")); STOCKITEM(wxID_SAVE, _("&Save"), _("Save")); + STOCKITEM(wxID_SAVEAS, _("&Save as"), _("Save as")); STOCKITEM(wxID_SELECT_COLOR, _("&Color"), _("Color")); STOCKITEM(wxID_SELECT_FONT, _("&Font"), _("Font")); STOCKITEM(wxID_SORT_ASCENDING, _("&Ascending"), _("Ascending")); From 77aa5fa0275909c411620e2cdf8aa7ce47eecef9 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 14 Aug 2011 15:42:35 +0000 Subject: [PATCH 004/167] fixing open application event handling, fixes #13397 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68692 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/osx/cocoa/utils.mm | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/osx/cocoa/utils.mm b/src/osx/cocoa/utils.mm index cb71db77a3..9f57601f84 100644 --- a/src/osx/cocoa/utils.mm +++ b/src/osx/cocoa/utils.mm @@ -53,6 +53,18 @@ void wxBell() - (void)applicationWillFinishLaunching:(NSNotification *)application { wxUnusedVar(application); + + // we must install our handlers later than setting the app delegates, because otherwise our handlers + // get overwritten + + NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; + + [appleEventManager setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass andEventID:kAEGetURL]; + + [appleEventManager setEventHandler:self andSelector:@selector(handleOpenAppEvent:withReplyEvent:) + forEventClass:kCoreEventClass andEventID:kAEOpenApplication]; + } - (void)application:(NSApplication *)sender openFiles:(NSArray *)fileNames @@ -69,13 +81,6 @@ void wxBell() wxTheApp->MacOpenFiles(fileList); } -- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender -{ - wxUnusedVar(sender); - wxTheApp->MacNewFile() ; - return NO; -} - - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename { wxUnusedVar(sender); @@ -101,6 +106,13 @@ void wxBell() wxTheApp->MacOpenURL(cf.AsString()) ; } +- (void)handleOpenAppEvent:(NSAppleEventDescriptor *)event + withReplyEvent:(NSAppleEventDescriptor *)replyEvent +{ + wxUnusedVar(replyEvent); + wxTheApp->MacNewFile() ; +} + /* Allowable return values are: NSTerminateNow - it is ok to proceed with termination @@ -239,10 +251,6 @@ bool wxApp::DoInitGui() wxNSAppController* controller = [[wxNSAppController alloc] init]; [NSApp setDelegate:controller]; - NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; - [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:) - forEventClass:kInternetEventClass andEventID:kAEGetURL]; - // calling finishLaunching so early before running the loop seems to trigger some 'MenuManager compatibility' which leads // to the duplication of menus under 10.5 and a warning under 10.6 #if 0 From 6a0d7a989c5e58d434badd69a9bb16bde8dcd0c0 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 14 Aug 2011 15:43:30 +0000 Subject: [PATCH 005/167] fixing comment git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68693 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/osx/cocoa/utils.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osx/cocoa/utils.mm b/src/osx/cocoa/utils.mm index 9f57601f84..225c9d487c 100644 --- a/src/osx/cocoa/utils.mm +++ b/src/osx/cocoa/utils.mm @@ -54,8 +54,8 @@ void wxBell() - (void)applicationWillFinishLaunching:(NSNotification *)application { wxUnusedVar(application); - // we must install our handlers later than setting the app delegates, because otherwise our handlers - // get overwritten + // we must install our handlers later than setting the app delegate, because otherwise our handlers + // get overwritten in the meantime NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; From f4cb7c58da30c8dde304bb7c3b83af3ddba6c9c2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 14 Aug 2011 19:39:31 +0000 Subject: [PATCH 006/167] Fix return value of wxMBConvUTF8::ToWChar() when not using MAP_INVALID_UTF8_NOT. wxMBConvUTF8::ToWChar() was off by 1 when the input length was explicitly specified, the extra NUL should only be added in the implicit length case. This bug didn't occur for the default wxMBConvUTF8 object as it simply forwarded to the base class wxMBConvStrictUTF8 implementation but it happened when MAP_INVALID_UTF8_TO_OCTAL or MAP_INVALID_UTF8_TO_PUA was used. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68694 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/strconv.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index 170ad719bd..9c6299a5d3 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -1230,7 +1230,10 @@ size_t wxMBConvUTF8::ToWChar(wchar_t *buf, size_t n, size_t len = 0; - while ((srcLen == wxNO_LEN ? *psz : srcLen--) && ((!buf) || (len < n))) + // The length can be either given explicitly or computed implicitly for the + // NUL-terminated strings. + const bool isNulTerminated = srcLen == wxNO_LEN; + while ((isNulTerminated ? *psz : srcLen--) && ((!buf) || (len < n))) { const char *opsz = psz; bool invalid = false; @@ -1364,10 +1367,17 @@ size_t wxMBConvUTF8::ToWChar(wchar_t *buf, size_t n, } } - if (srcLen == wxNO_LEN && buf && (len < n)) - *buf = 0; + if ( isNulTerminated ) + { + // Add the trailing NUL in this case if we have a large enough buffer. + if ( buf && (len < n) ) + *buf = 0; - return len + 1; + // And count it in any case. + len++; + } + + return len; } static inline bool isoctal(wchar_t wch) From d0f93bc7dcf35f0e136cd8a5fa22ad6bdf1c2501 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Tue, 16 Aug 2011 07:02:37 +0000 Subject: [PATCH 007/167] Avoid creating rect with negative size while clipping to DC size. Also, don't convert result of wxDC::GetSize() to device coords, it's already device coords. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68717 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/dcgraph.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index a06cd25382..1f7295a12e 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -896,6 +896,17 @@ bool wxGCDCImpl::DoStretchBlit( return false; } + wxRect subrect(source->LogicalToDeviceX(xsrc), + source->LogicalToDeviceY(ysrc), + source->LogicalToDeviceXRel(srcWidth), + source->LogicalToDeviceYRel(srcHeight)); + // clip the subrect down to the size of the source DC + wxRect clip; + source->GetSize(&clip.width, &clip.height); + subrect.Intersect(clip); + if (subrect.width == 0) + return true; + bool retval = true; wxCompositionMode formerMode = m_graphicContext->GetCompositionMode(); @@ -913,21 +924,6 @@ bool wxGCDCImpl::DoStretchBlit( ysrcMask = ysrc; } - wxRect subrect(source->LogicalToDeviceX(xsrc), - source->LogicalToDeviceY(ysrc), - source->LogicalToDeviceXRel(srcWidth), - source->LogicalToDeviceYRel(srcHeight)); - - // if needed clip the subrect down to the size of the source DC - wxCoord sw, sh; - source->GetSize(&sw, &sh); - sw = source->LogicalToDeviceXRel(sw); - sh = source->LogicalToDeviceYRel(sh); - if (subrect.x + subrect.width > sw) - subrect.width = sw - subrect.x; - if (subrect.y + subrect.height > sh) - subrect.height = sh - subrect.y; - wxBitmap blit = source->GetAsBitmap( &subrect ); if ( blit.IsOk() ) From 5266f345907f3e283169b8603c04653f0e8393f4 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 11:55:39 +0000 Subject: [PATCH 008/167] adapt defines git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68718 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/accel.h | 5 +++-- include/wx/defs.h | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/wx/accel.h b/include/wx/accel.h index 6d0e2701ea..ca2d8dfb0e 100644 --- a/include/wx/accel.h +++ b/include/wx/accel.h @@ -34,10 +34,11 @@ enum wxAcceleratorEntryFlags wxACCEL_CTRL = 0x0002, // hold Ctrl key down wxACCEL_SHIFT = 0x0004, // hold Shift key down #if defined(__WXMAC__) || defined(__WXCOCOA__) - wxACCEL_CMD = 0x0008 // Command key on OS X + wxACCEL_RAW_CTRL= 0x0008, // #else - wxACCEL_CMD = wxACCEL_CTRL + wxACCEL_RAW_CTRL= wxACCEL_CTRL, #endif + wxACCEL_CMD = wxACCEL_CTRL }; // ---------------------------------------------------------------------------- diff --git a/include/wx/defs.h b/include/wx/defs.h index 3b66b2e0a4..0fcac961c8 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -2572,10 +2572,11 @@ enum wxKeyModifier wxMOD_META = 0x0008, wxMOD_WIN = wxMOD_META, #if defined(__WXMAC__) || defined(__WXCOCOA__) - wxMOD_CMD = wxMOD_META, + wxMOD_RAW_CONTROL = wxMOD_META, #else - wxMOD_CMD = wxMOD_CONTROL, + wxMOD_RAW_CONTROL = wxMOD_CONTROL, #endif + wxMOD_CMD = wxMOD_CONTROL, wxMOD_ALL = 0xffff }; From 3c5f62640d5072b3ab9116a3852294ab58ebbfbb Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 12:00:52 +0000 Subject: [PATCH 009/167] adapt defines for ctrl/command key git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68719 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/accelcmn.cpp | 2 +- src/osx/accel.cpp | 4 ++-- src/osx/cocoa/menuitem.mm | 3 +++ src/osx/dialog_osx.cpp | 2 +- src/osx/textctrl_osx.cpp | 2 +- src/osx/window_osx.cpp | 4 ++-- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/common/accelcmn.cpp b/src/common/accelcmn.cpp index f52fc05de3..4d05f3de4d 100644 --- a/src/common/accelcmn.cpp +++ b/src/common/accelcmn.cpp @@ -307,7 +307,7 @@ wxString wxAcceleratorEntry::ToString() const int flags = GetFlags(); if ( flags & wxACCEL_ALT ) text += _("Alt+"); - if ( flags & (wxACCEL_CTRL | wxACCEL_CMD) ) + if ( flags & wxACCEL_CTRL ) text += _("Ctrl+"); if ( flags & wxACCEL_SHIFT ) text += _("Shift+"); diff --git a/src/osx/accel.cpp b/src/osx/accel.cpp index 14f0b1887a..dbba6195bc 100644 --- a/src/osx/accel.cpp +++ b/src/osx/accel.cpp @@ -93,10 +93,10 @@ int wxAcceleratorTable::GetCommand( wxKeyEvent &event ) { wxAcceleratorEntry *entry = node->GetData(); if ((event.m_keyCode == entry->GetKeyCode()) && - (((entry->GetFlags() & wxACCEL_CTRL) != 0) == event.ControlDown()) && + (((entry->GetFlags() & wxACCEL_RAW_CTRL) != 0) == event.ControlDown()) && (((entry->GetFlags() & wxACCEL_SHIFT) != 0) == event.ShiftDown()) && (((entry->GetFlags() & wxACCEL_ALT) != 0) == event.AltDown()) && - (((entry->GetFlags() & wxACCEL_CMD) != 0) == event.CmdDown())) + (((entry->GetFlags() & wxACCEL_CTRL) != 0) == event.CmdDown())) { return entry->GetCommand(); } diff --git a/src/osx/cocoa/menuitem.mm b/src/osx/cocoa/menuitem.mm index 543b64f321..a25ee8bcfa 100644 --- a/src/osx/cocoa/menuitem.mm +++ b/src/osx/cocoa/menuitem.mm @@ -137,6 +137,9 @@ void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry* if (entry->GetFlags() & wxACCEL_CTRL) modifiers |= NSCommandKeyMask; + if (entry->GetFlags() & wxACCEL_RAW_CTRL) + modifiers |= NSControlKeyMask; + if (entry->GetFlags() & wxACCEL_ALT) modifiers |= NSAlternateKeyMask ; diff --git a/src/osx/dialog_osx.cpp b/src/osx/dialog_osx.cpp index e4088d6cfc..835afaaa24 100644 --- a/src/osx/dialog_osx.cpp +++ b/src/osx/dialog_osx.cpp @@ -80,7 +80,7 @@ wxDialog::~wxDialog() // about it bool wxDialog::IsEscapeKey(const wxKeyEvent& event) { - if ( event.GetKeyCode() == '.' && event.GetModifiers() == wxMOD_CMD ) + if ( event.GetKeyCode() == '.' && event.GetModifiers() == wxMOD_CONTROL ) return true; return wxDialogBase::IsEscapeKey(event); diff --git a/src/osx/textctrl_osx.cpp b/src/osx/textctrl_osx.cpp index 8c2f1d83da..a49ff2cfe2 100644 --- a/src/osx/textctrl_osx.cpp +++ b/src/osx/textctrl_osx.cpp @@ -339,7 +339,7 @@ void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event) void wxTextCtrl::OnKeyDown(wxKeyEvent& event) { - if ( event.GetModifiers() == wxMOD_CMD ) + if ( event.GetModifiers() == wxMOD_CONTROL ) { switch( event.GetKeyCode() ) { diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 00115ba251..065426269a 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -2667,9 +2667,9 @@ bool wxWindowMac::RegisterHotKey(int hotkeyId, int modifiers, int keycode) mac_modifiers |= optionKey; if ( modifiers & wxMOD_SHIFT ) mac_modifiers |= shiftKey; - if ( modifiers & wxMOD_CONTROL ) + if ( modifiers & wxMOD_RAW_CONTROL ) mac_modifiers |= controlKey; - if ( modifiers & wxMOD_META ) + if ( modifiers & wxMOD_CONTROL ) mac_modifiers |= cmdKey; EventHotKeyRef hotKeyRef; From 8680646d5c35b038a6370dcef7756c081fc6f959 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 12:01:27 +0000 Subject: [PATCH 010/167] emulate more arrow keys on non msw platforms git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68720 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/textcmn.cpp | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/common/textcmn.cpp b/src/common/textcmn.cpp index 9e04aedcaa..76b0916d21 100644 --- a/src/common/textcmn.cpp +++ b/src/common/textcmn.cpp @@ -940,12 +940,47 @@ int wxTextCtrlBase::overflow(int c) bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) { + bool handled = false; // we have a native implementation for Win32 and so don't need this one #ifndef __WIN32__ wxChar ch = 0; int keycode = event.GetKeyCode(); + + long from, to; + GetSelection(&from,&to); + long insert = GetInsertionPoint(); + long last = GetLastPosition(); + + // catch arrow left and right + switch ( keycode ) { + case WXK_LEFT: + if ( event.ShiftDown() ) + SetSelection( (from > 0 ? from - 1 : 0) , to ); + else + { + if ( from != to ) + insert = from; + else if ( insert > 0 ) + insert -= 1; + SetInsertionPoint( insert ); + } + handled = true; + break; + case WXK_RIGHT: + if ( event.ShiftDown() ) + SetSelection( from, (to < last ? to + 1 : last) ); + else + { + if ( from != to ) + insert = to; + else if ( insert < last ) + insert += 1; + SetInsertionPoint( insert ); + } + handled = true; + break; case WXK_NUMPAD0: case WXK_NUMPAD1: case WXK_NUMPAD2: @@ -991,6 +1026,7 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) const long pos = GetInsertionPoint(); if ( pos < GetLastPosition() ) Remove(pos, pos + 1); + handled = true; } break; @@ -1000,6 +1036,7 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) const long pos = GetInsertionPoint(); if ( pos > 0 ) Remove(pos - 1, pos); + handled = true; } break; @@ -1031,13 +1068,13 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) { WriteText(ch); - return true; + handled = true; } #else // __WIN32__ wxUnusedVar(event); #endif // !__WIN32__/__WIN32__ - return false; + return handled; } // do the window-specific processing after processing the update event From 3e7c34b5a19630968d4857dbbef04b6d87dacc63 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 12:17:13 +0000 Subject: [PATCH 011/167] support for raw ctrl shortcut git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68721 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/osx/carbon/uma.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/osx/carbon/uma.cpp b/src/osx/carbon/uma.cpp index fd077da113..a89ca35d15 100644 --- a/src/osx/carbon/uma.cpp +++ b/src/osx/carbon/uma.cpp @@ -96,6 +96,9 @@ void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , wxAcceleratorEn if (entry->GetFlags() & wxACCEL_SHIFT) modifiers |= kMenuShiftModifier ; + if (entry->GetFlags() & wxACCEL_RAW_CTRL) + modifiers |= kMenuControlModifier ; + SInt16 glyph = 0 ; SInt16 macKey = key ; if ( key >= WXK_F1 && key <= WXK_F15 ) From ee442831984b69b4dc13bfe976dd2b57cb62a2ab Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 12:17:59 +0000 Subject: [PATCH 012/167] adjust init to standard git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68722 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/html/htmlctrl/webkit/webkit.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/html/htmlctrl/webkit/webkit.mm b/src/html/htmlctrl/webkit/webkit.mm index 1152845843..9c0d8e515d 100644 --- a/src/html/htmlctrl/webkit/webkit.mm +++ b/src/html/htmlctrl/webkit/webkit.mm @@ -796,7 +796,7 @@ void wxWebKitCtrl::MacVisibilityChanged(){ - initWithWxWindow: (wxWebKitCtrl*)inWindow { - [super init]; + self = [super init]; webKitWindow = inWindow; // non retained return self; } @@ -877,7 +877,7 @@ void wxWebKitCtrl::MacVisibilityChanged(){ - initWithWxWindow: (wxWebKitCtrl*)inWindow { - [super init]; + self = [super init]; webKitWindow = inWindow; // non retained return self; } From 04f1f9b7735fa68de9eb173a610f50479a294a43 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 16 Aug 2011 12:24:28 +0000 Subject: [PATCH 013/167] wxMSW compilation fix when not using PCH. Add missing "wx/menu.h" include. Coses #13399. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68723 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/toplevel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 9e068789c8..3d7ccb58b2 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -33,6 +33,7 @@ #include "wx/log.h" #include "wx/intl.h" #include "wx/frame.h" + #include "wx/menu.h" #include "wx/containr.h" // wxSetFocusToChild() #include "wx/module.h" #endif //WX_PRECOMP From 773db5dfb386719b34ea90c1885ca1f082717b7f Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 12:42:56 +0000 Subject: [PATCH 014/167] supporting full style mask git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68724 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/osx/cocoa/nonownedwnd.mm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/osx/cocoa/nonownedwnd.mm b/src/osx/cocoa/nonownedwnd.mm index 29e42db165..f95db4d67a 100644 --- a/src/osx/cocoa/nonownedwnd.mm +++ b/src/osx/cocoa/nonownedwnd.mm @@ -858,6 +858,7 @@ void wxNonOwnedWindowCocoaImpl::Maximize(bool WXUNUSED(maximize)) typedef struct { + NSUInteger m_formerStyleMask; int m_formerLevel; NSRect m_formerFrame; } FullScreenData ; @@ -878,6 +879,7 @@ bool wxNonOwnedWindowCocoaImpl::ShowFullScreen(bool show, long WXUNUSED(style)) m_macFullScreenData = data ; data->m_formerLevel = [m_macWindow level]; data->m_formerFrame = [m_macWindow frame]; + data->m_formerStyleMask = [m_macWindow styleMask]; #if 0 // CGDisplayCapture( kCGDirectMainDisplay ); //[m_macWindow setLevel:NSMainMenuWindowLevel+1/*CGShieldingWindowLevel()*/]; @@ -885,6 +887,12 @@ bool wxNonOwnedWindowCocoaImpl::ShowFullScreen(bool show, long WXUNUSED(style)) NSRect screenframe = [[NSScreen mainScreen] frame]; NSRect frame = NSMakeRect (0, 0, 100, 100); NSRect contentRect; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + if ( [ m_macWindow respondsToSelector:@selector(setStyleMask:) ] ) + [m_macWindow setStyleMask:data->m_formerStyleMask & ~ NSResizableWindowMask]; +#endif + contentRect = [NSWindow contentRectForFrameRect: frame styleMask: [m_macWindow styleMask]]; screenframe.origin.y += (frame.origin.y - contentRect.origin.y); @@ -907,6 +915,10 @@ bool wxNonOwnedWindowCocoaImpl::ShowFullScreen(bool show, long WXUNUSED(style)) #endif [m_macWindow setFrame:data->m_formerFrame display:YES]; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + if ( [ m_macWindow respondsToSelector:@selector(setStyleMask:) ] ) + [m_macWindow setStyleMask:data->m_formerStyleMask]; +#endif delete data ; m_macFullScreenData = NULL ; From cfc77ac09a13471b16acc028520da862b5debc0d Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 13:36:24 +0000 Subject: [PATCH 015/167] adapting to new ctrl constant handling on OSX git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68725 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- interface/wx/accel.h | 7 +++++-- interface/wx/defs.h | 17 ++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/interface/wx/accel.h b/interface/wx/accel.h index 974731fab6..580d30033d 100644 --- a/interface/wx/accel.h +++ b/interface/wx/accel.h @@ -16,13 +16,16 @@ enum wxAcceleratorEntryFlags /** hold Alt key down */ wxACCEL_ALT, - /** hold Ctrl key down */ + /** hold Ctrl key down, corresponds to Command key on OS X */ wxACCEL_CTRL, /** hold Shift key down */ wxACCEL_SHIFT, - /** Command key on OS X; identic to wxACCEL_CTRL on other platforms. */ + /** corresponds to real Ctrl key on OS X, identic to @c wxACCEL_CTRL on other platforms */ + wxACCEL_RAW_CTRL, + + /** deprecated, identic to @c wxACCEL_CTRL on all platforms. */ wxACCEL_CMD }; diff --git a/interface/wx/defs.h b/interface/wx/defs.h index 2513b04c38..f9f1cc1541 100644 --- a/interface/wx/defs.h +++ b/interface/wx/defs.h @@ -653,20 +653,19 @@ enum wxKeyModifier { wxMOD_NONE = 0x0000, wxMOD_ALT = 0x0001, + /** Ctlr Key, corresponds to Command key on OS X */ wxMOD_CONTROL = 0x0002, wxMOD_ALTGR = wxMOD_ALT | wxMOD_CONTROL, wxMOD_SHIFT = 0x0004, wxMOD_META = 0x0008, wxMOD_WIN = wxMOD_META, - - /** - Notice that @c wxMOD_CMD should be used instead of @c wxMOD_CONTROL - in portable code to account for the fact that although - @c Control modifier exists under Mac OS, it is not used for the same - purpose as under Windows or Unix there while the special Mac-specific - @c Command modifier is used in exactly the same way. - */ - wxMOD_CMD = wxMOD_META, + + /** used to describe the true Ctrl Key under OSX, + identic to @c wxMOD_CONTROL on other platforms */ + wxMOD_RAW_CONTROL, + + /** deprecated, identic to @c wxMOD_CONTROL on all platforms */ + wxMOD_CMD = wxMOD_CONTROL, wxMOD_ALL = 0xffff }; From 3bc6d534030f0677d6c7512a4d56a3919d48b6ee Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 13:45:05 +0000 Subject: [PATCH 016/167] adapting to new ctrl constant handling on OSX git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68726 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/generic/grid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 8326934f7f..9cd2da322b 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -3664,7 +3664,7 @@ wxGrid::DoGridCellDrag(wxMouseEvent& event, switch ( event.GetModifiers() ) { - case wxMOD_CMD: + case wxMOD_CONTROL: if ( m_selectedBlockCorner == wxGridNoCellCoords) m_selectedBlockCorner = coords; UpdateBlockBeingSelected(m_selectedBlockCorner, coords); From 675ec6655eb3a67caa1d648f912d754ae328c38f Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 16 Aug 2011 13:46:56 +0000 Subject: [PATCH 017/167] adapting to new ctrl constant handling on OSX git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68727 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/cmdproc.cpp | 4 ++-- src/common/stockitem.cpp | 22 +++++++++++----------- src/richtext/richtextctrl.cpp | 12 ++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/common/cmdproc.cpp b/src/common/cmdproc.cpp index f59886d0a5..7de08c2790 100644 --- a/src/common/cmdproc.cpp +++ b/src/common/cmdproc.cpp @@ -62,8 +62,8 @@ wxCommandProcessor::wxCommandProcessor(int maxCommands) #endif // wxUSE_MENUS #if wxUSE_ACCEL - m_undoAccelerator = '\t' + wxAcceleratorEntry(wxACCEL_CMD, 'Z').ToString(); - m_redoAccelerator = '\t' + wxAcceleratorEntry(wxACCEL_CMD, 'Y').ToString(); + m_undoAccelerator = '\t' + wxAcceleratorEntry(wxACCEL_CTRL, 'Z').ToString(); + m_redoAccelerator = '\t' + wxAcceleratorEntry(wxACCEL_CTRL, 'Y').ToString(); #endif // wxUSE_ACCEL m_lastSavedCommand = diff --git a/src/common/stockitem.cpp b/src/common/stockitem.cpp index 2df465503d..da579718b1 100644 --- a/src/common/stockitem.cpp +++ b/src/common/stockitem.cpp @@ -281,17 +281,17 @@ wxAcceleratorEntry wxGetStockAccelerator(wxWindowID id) switch (id) { - STOCKITEM(wxID_COPY, wxACCEL_CMD,'C') - STOCKITEM(wxID_CUT, wxACCEL_CMD,'X') - STOCKITEM(wxID_FIND, wxACCEL_CMD,'F') - STOCKITEM(wxID_HELP, wxACCEL_CMD,'H') - STOCKITEM(wxID_NEW, wxACCEL_CMD,'N') - STOCKITEM(wxID_OPEN, wxACCEL_CMD,'O') - STOCKITEM(wxID_PASTE, wxACCEL_CMD,'V') - STOCKITEM(wxID_REDO, wxACCEL_CMD | wxACCEL_SHIFT,'Z') - STOCKITEM(wxID_REPLACE, wxACCEL_CMD,'R') - STOCKITEM(wxID_SAVE, wxACCEL_CMD,'S') - STOCKITEM(wxID_UNDO, wxACCEL_CMD,'Z') + STOCKITEM(wxID_COPY, wxACCEL_CTRL,'C') + STOCKITEM(wxID_CUT, wxACCEL_CTRL,'X') + STOCKITEM(wxID_FIND, wxACCEL_CTRL,'F') + STOCKITEM(wxID_HELP, wxACCEL_CTRL,'H') + STOCKITEM(wxID_NEW, wxACCEL_CTRL,'N') + STOCKITEM(wxID_OPEN, wxACCEL_CTRL,'O') + STOCKITEM(wxID_PASTE, wxACCEL_CTRL,'V') + STOCKITEM(wxID_REDO, wxACCEL_CTRL | wxACCEL_SHIFT,'Z') + STOCKITEM(wxID_REPLACE, wxACCEL_CTRL,'R') + STOCKITEM(wxID_SAVE, wxACCEL_CTRL,'S') + STOCKITEM(wxID_UNDO, wxACCEL_CTRL,'Z') default: // set the wxAcceleratorEntry to return into an invalid state: diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index f5039443c5..43d636458b 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -293,12 +293,12 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va // Accelerators wxAcceleratorEntry entries[6]; - entries[0].Set(wxACCEL_CMD, (int) 'C', wxID_COPY); - entries[1].Set(wxACCEL_CMD, (int) 'X', wxID_CUT); - entries[2].Set(wxACCEL_CMD, (int) 'V', wxID_PASTE); - entries[3].Set(wxACCEL_CMD, (int) 'A', wxID_SELECTALL); - entries[4].Set(wxACCEL_CMD, (int) 'Z', wxID_UNDO); - entries[5].Set(wxACCEL_CMD, (int) 'Y', wxID_REDO); + entries[0].Set(wxACCEL_CTRL, (int) 'C', wxID_COPY); + entries[1].Set(wxACCEL_CTRL, (int) 'X', wxID_CUT); + entries[2].Set(wxACCEL_CTRL, (int) 'V', wxID_PASTE); + entries[3].Set(wxACCEL_CTRL, (int) 'A', wxID_SELECTALL); + entries[4].Set(wxACCEL_CTRL, (int) 'Z', wxID_UNDO); + entries[5].Set(wxACCEL_CTRL, (int) 'Y', wxID_REDO); wxAcceleratorTable accel(6, entries); SetAcceleratorTable(accel); From 63509fb3c424dd69d8f5db35f7ae16950b9a3595 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Tue, 16 Aug 2011 20:52:15 +0000 Subject: [PATCH 018/167] Implemented non-selection of content when setting focus via the keyboard. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68749 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 2 ++ src/msw/window.cpp | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index 1bfcf05b02..2b53227ba1 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -470,6 +470,8 @@ MSW: - Added wxGCDC(wxEnhMetaFileDC) ctor (Marcin Wojdyr). - Added wxTopLevelWindow::MSWGetSystemMenu(). +- Multiline text controls no longer select all content when gaining focus from + the keyboard. 2.9.2: (released 2011-07-05) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 5e2e43a438..3bdd324931 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3100,6 +3100,13 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, processed = true; } + else if (IsOfStandardClass() && IsKindOf(CLASSINFO(wxTextCtrl)) && ((wxTextCtrl*)this)->IsMultiLine()) + { + rc.result = MSWDefWindowProc(message, wParam, lParam); + // Clear the DLGC_HASSETSEL bit from the return value + rc.result &= ~DLGC_HASSETSEL; + processed = true; + } //else: get the dlg code from the DefWindowProc() break; From 827fb0e455814783e74a0a211b408e788a386246 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Wed, 17 Aug 2011 08:38:00 +0000 Subject: [PATCH 019/167] Better text control non-selection solution git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68753 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/textctrl.cpp | 3 +++ src/msw/window.cpp | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 850ea6ee93..4e2171fbfe 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -1951,6 +1951,9 @@ WXLRESULT wxTextCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPara // live with it. lRc = lDlgCode; } + if (IsMultiLine()) + // Clear the DLGC_HASSETSEL bit from the return value + lRc &= ~DLGC_HASSETSEL; } break; diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 3bdd324931..5e2e43a438 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3100,13 +3100,6 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, processed = true; } - else if (IsOfStandardClass() && IsKindOf(CLASSINFO(wxTextCtrl)) && ((wxTextCtrl*)this)->IsMultiLine()) - { - rc.result = MSWDefWindowProc(message, wParam, lParam); - // Clear the DLGC_HASSETSEL bit from the return value - rc.result &= ~DLGC_HASSETSEL; - processed = true; - } //else: get the dlg code from the DefWindowProc() break; From 2032371b3b1fa438e441ac3e5e63b792f64015a7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 17 Aug 2011 10:35:25 +0000 Subject: [PATCH 020/167] Restore stock item labels mistakenly removed by r68641. The patch adding separate string for the labels with mnemonics and the ones without them has somehow managed to remove entries for 10 stock ids. Restore them now. Closes #13403. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68756 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/stockitem.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/common/stockitem.cpp b/src/common/stockitem.cpp index da579718b1..0892b1bfe9 100644 --- a/src/common/stockitem.cpp +++ b/src/common/stockitem.cpp @@ -167,8 +167,11 @@ wxString wxGetStockLabel(wxWindowID id, long flags) STOCKITEM(wxID_INDEX, _("&Index"), _("Index")); STOCKITEM(wxID_INFO, _("&Info"), _("Info")); STOCKITEM(wxID_ITALIC, _("&Italic"), _("Italic")); + STOCKITEM(wxID_JUMP_TO, _("&Jump to"), _("Jump to")); STOCKITEM(wxID_JUSTIFY_CENTER, _("Centered"), _("Centered")); STOCKITEM(wxID_JUSTIFY_FILL, _("Justified"), _("Justified")); + STOCKITEM(wxID_JUSTIFY_LEFT, _("Align Left"), _("Align Left")); + STOCKITEM(wxID_JUSTIFY_RIGHT, _("Align Right"), _("Align Right")); STOCKITEM(wxID_LAST, _("&Last"), _("Last")); STOCKITEM(wxID_NETWORK, _("&Network"), _("Network")); STOCKITEM(wxID_NEW, _("&New"), _("New")); @@ -184,12 +187,15 @@ wxString wxGetStockLabel(wxWindowID id, long flags) STOCKITEM(wxID_REFRESH, _("Refresh"), _("Refresh")); STOCKITEM(wxID_REMOVE, _("Remove"), _("Remove")); STOCKITEM(wxID_REPLACE, _("Rep&lace"), _("Replace")); + STOCKITEM(wxID_REVERT_TO_SAVED, _("Revert to Saved"), _("Revert to Saved")); STOCKITEM(wxID_SAVE, _("&Save"), _("Save")); STOCKITEM(wxID_SAVEAS, _("&Save as"), _("Save as")); + STOCKITEM(wxID_SELECTALL, _("Select &All"), _("Select All")); STOCKITEM(wxID_SELECT_COLOR, _("&Color"), _("Color")); STOCKITEM(wxID_SELECT_FONT, _("&Font"), _("Font")); STOCKITEM(wxID_SORT_ASCENDING, _("&Ascending"), _("Ascending")); STOCKITEM(wxID_SORT_DESCENDING, _("&Descending"), _("Descending")); + STOCKITEM(wxID_SPELL_CHECK, _("&Spell Check"), _("Spell Check")); STOCKITEM(wxID_STOP, _("&Stop"), _("Stop")); STOCKITEM(wxID_STRIKETHROUGH, _("&Strikethrough"), _("Strikethrough")); STOCKITEM(wxID_TOP, _("&Top"), _("Top")); @@ -199,6 +205,10 @@ wxString wxGetStockLabel(wxWindowID id, long flags) STOCKITEM(wxID_UNINDENT, _("&Unindent"), _("Unindent")); STOCKITEM(wxID_UP, _("&Up"), _("Up")); STOCKITEM(wxID_YES, _("&Yes"), _("Yes")); + STOCKITEM(wxID_ZOOM_100, _("&Actual Size"), _("Actual Size")); + STOCKITEM(wxID_ZOOM_FIT, _("Zoom to &Fit"), _("Zoom to Fit")); + STOCKITEM(wxID_ZOOM_IN, _("Zoom &In"), _("Zoom In")); + STOCKITEM(wxID_ZOOM_OUT, _("Zoom &Out"), _("Zoom Out")); default: wxFAIL_MSG( wxT("invalid stock item ID") ); From ee19ab6d804cd61575ca03131888c7d6f2a4daa1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 17 Aug 2011 10:35:29 +0000 Subject: [PATCH 021/167] Use correct format specifier for thread id in the sample. Thread id is an (unsigned) long, not just unsigned, so use "%lx" to print it instead of "%x" to avoid asserts in formatting code. Closes #13404. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68757 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- samples/thread/thread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/thread/thread.cpp b/samples/thread/thread.cpp index 6b0903cb82..1e5c3ee9fb 100644 --- a/samples/thread/thread.cpp +++ b/samples/thread/thread.cpp @@ -479,7 +479,7 @@ MyFrame::DoLogRecord(wxLogLevel level, wxDateTime(info.timestamp).FormatISOTime(), info.threadId == wxThread::GetMainId() ? wxString("main") - : wxString::Format("%x", info.threadId), + : wxString::Format("%lx", info.threadId), msg + "\n" ); } From d06c3098ab6add89fbee763416d5e5546c66fe23 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Wed, 17 Aug 2011 21:01:09 +0000 Subject: [PATCH 022/167] Improved BMP decoding. The BMP decoder did not handle images that are not stored upside down but straight up (in which case the height is negative). Also with RLE4 or RLE8 compressed images the 'end of scanline' RLE marker was not handled correctly. Fixed the issues and added a unit test for them. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68766 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagbmp.cpp | 34 +++++++++++++++++++++-------- tests/image/horse_grey.bmp | Bin 0 -> 41080 bytes tests/image/horse_grey_flipped.bmp | Bin 0 -> 41080 bytes tests/image/horse_rle4.bmp | Bin 0 -> 19012 bytes tests/image/horse_rle4_flipped.bmp | Bin 0 -> 19012 bytes tests/image/horse_rle8.bmp | Bin 0 -> 41768 bytes tests/image/horse_rle8_flipped.bmp | Bin 0 -> 41768 bytes tests/image/image.cpp | 22 +++++++++++++++++++ 8 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 tests/image/horse_grey.bmp create mode 100644 tests/image/horse_grey_flipped.bmp create mode 100644 tests/image/horse_rle4.bmp create mode 100644 tests/image/horse_rle4_flipped.bmp create mode 100644 tests/image/horse_rle8.bmp create mode 100644 tests/image/horse_rle8_flipped.bmp diff --git a/src/common/imagbmp.cpp b/src/common/imagbmp.cpp index 631130805c..f3c7f8c040 100644 --- a/src/common/imagbmp.cpp +++ b/src/common/imagbmp.cpp @@ -533,6 +533,14 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, wxON_BLOCK_EXIT1(&BMPPalette::Free, cmap); + bool isUpsideDown = true; + + if (height < 0) + { + isUpsideDown = false; + height = -height; + } + // destroy existing here instead of: image->Destroy(); image->Create(width, height); @@ -702,9 +710,10 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, // this case (see #10915) bool hasValidAlpha = false; - /* BMPs are stored upside down */ - for ( int line = (height - 1); line >= 0; line-- ) + for ( int row = 0; row < height; row++ ) { + int line = isUpsideDown ? height - 1 - row : row; + int linepos = 0; for ( int column = 0; column < width ; ) { @@ -734,21 +743,24 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, { if ( aByte == 0 ) { - if ( column > 0 ) - column = width; + // end of scanline marker + column = width; + row--; } else if ( aByte == 1 ) { + // end of RLE data marker, stop decoding column = width; - line = -1; + row = height; } else if ( aByte == 2 ) { + // delta marker, move in image aByte = stream.GetC(); column += aByte; linepos = column * bpp / 4; aByte = stream.GetC(); - line -= aByte; // upside down + row += aByte; // upside down } else { @@ -817,20 +829,24 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, { if ( aByte == 0 ) { - /* column = width; */ + // end of scanline marker + column = width; + row--; } else if ( aByte == 1 ) { + // end of RLE data marker, stop decoding column = width; - line = -1; + row = height; } else if ( aByte == 2 ) { + // delta marker, move in image aByte = stream.GetC(); column += aByte; linepos = column * bpp / 8; aByte = stream.GetC(); - line += aByte; + row -= aByte; } else { diff --git a/tests/image/horse_grey.bmp b/tests/image/horse_grey.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b99ffd63baafde14d80d6b432002b288ba9ce9d0 GIT binary patch literal 41080 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 Y0B%^CQm{;xg0S+LD=a<3fB1+04{nynGXMYp literal 0 HcmV?d00001 diff --git a/tests/image/horse_grey_flipped.bmp b/tests/image/horse_grey_flipped.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7cd67f3cb32ec066aebc1f6fe842c73b7252e63d GIT binary patch literal 41080 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 Apa1{> literal 0 HcmV?d00001 diff --git a/tests/image/horse_rle4.bmp b/tests/image/horse_rle4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bdc43a1f36c02428d6d9eb1c86d0267d4d9c0839 GIT binary patch literal 19012 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 literal 0 HcmV?d00001 diff --git a/tests/image/horse_rle4_flipped.bmp b/tests/image/horse_rle4_flipped.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6f231884282a011f84fa94d406563f0d5ba6a628 GIT binary patch literal 19012 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 literal 0 HcmV?d00001 diff --git a/tests/image/horse_rle8.bmp b/tests/image/horse_rle8.bmp new file mode 100644 index 0000000000000000000000000000000000000000..31dfc875715a23c5bad13c64019a185bd38653a7 GIT binary patch literal 41768 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

EXhZJlR3JAcU^>EM96 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 literal 0 HcmV?d00001 diff --git a/tests/image/horse_rle8_flipped.bmp b/tests/image/horse_rle8_flipped.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bd16370397f3360a22e620ae6f5204f803af8b09 GIT binary patch literal 41768 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 literal 0 HcmV?d00001 diff --git a/tests/image/image.cpp b/tests/image/image.cpp index 6b98ad4f3c..ae63591d8e 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -77,6 +77,7 @@ private: CPPUNIT_TEST( ReadCorruptedTGA ); CPPUNIT_TEST( GIFComment ); CPPUNIT_TEST( DibPadding ); + CPPUNIT_TEST( BMPFlippingAndRLECompression ); CPPUNIT_TEST_SUITE_END(); void LoadFromSocketStream(); @@ -90,6 +91,7 @@ private: void ReadCorruptedTGA(); void GIFComment(); void DibPadding(); + void BMPFlippingAndRLECompression(); DECLARE_NO_COPY_CLASS(ImageTestCase) }; @@ -1262,6 +1264,26 @@ void ImageTestCase::DibPadding() CPPUNIT_ASSERT( image.SaveFile(memOut, wxBITMAP_TYPE_ICO) ); } +static void CompareBMPImage(const wxString& file1, const wxString& file2) +{ + wxImage image1(file1); + CPPUNIT_ASSERT( image1.IsOk() ); + + wxImage image2(file2); + CPPUNIT_ASSERT( image2.IsOk() ); + + CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_BMP), image1, 0, &image2); +} + +void ImageTestCase::BMPFlippingAndRLECompression() +{ + CompareBMPImage("image/horse_grey.bmp", "image/horse_grey_flipped.bmp"); + + CompareBMPImage("image/horse_rle8.bmp", "image/horse_grey.bmp"); + CompareBMPImage("image/horse_rle8.bmp", "image/horse_rle8_flipped.bmp"); + + CompareBMPImage("image/horse_rle4.bmp", "image/horse_rle4_flipped.bmp"); +} #endif //wxUSE_IMAGE From 7ffc9affb41239c681e25ccccd6a2e55a6f0b81a Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Thu, 18 Aug 2011 13:15:43 +0000 Subject: [PATCH 023/167] Fixed saving TIFF images to wxMemoryOutputStream. Libtiff attempts to seek past the end of a stream and the behaviour for this can vary per stream implementation. Fixed failure to seek by filling the gap between the end of stream and new seek position with zeroes. Enabled a unit test which so far was disabled due to wxMemoryOutputStream failing to save a TIFF because of the seeking problem. Also closes #4089. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68772 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 38 ++++++++++++++++++++++++++++++++++++-- tests/image/image.cpp | 9 +-------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 2501e91f3e..59b7fb9b43 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -192,8 +192,42 @@ wxTIFFSeekOProc(thandle_t handle, toff_t off, int whence) { wxOutputStream *stream = (wxOutputStream*) handle; - return wxFileOffsetToTIFF(stream->SeekO((wxFileOffset)off, - wxSeekModeFromTIFF(whence))); + toff_t offset = wxFileOffsetToTIFF( + stream->SeekO((wxFileOffset)off, wxSeekModeFromTIFF(whence)) ); + + if (offset != (toff_t) -1 || whence != SEEK_SET) + { + return offset; + } + + + /* + Try to workaround problems with libtiff seeking past the end of streams. + + This occurs when libtiff is writing tag entries past the end of a + stream but hasn't written the directory yet (which will be placed + before the tags and contain offsets to the just written tags). + The behaviour for seeking past the end of a stream is not consistent + and doesn't work with for example wxMemoryOutputStream. When this type + of seeking fails (with SEEK_SET), fill in the gap with zeroes and try + again. + */ + + wxFileOffset streamLength = stream->GetLength(); + if (streamLength != wxInvalidOffset && (wxFileOffset) off > streamLength) + { + if (stream->SeekO(streamLength, wxFromStart) == wxInvalidOffset) + { + return (toff_t) -1; + } + + for (wxFileOffset i = 0; i < (wxFileOffset) off - streamLength; ++i) + { + stream->PutC(0); + } + } + + return wxFileOffsetToTIFF( stream->TellO() ); } int TIFFLINKAGEMODE diff --git a/tests/image/image.cpp b/tests/image/image.cpp index ae63591d8e..22384f5e1f 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -912,15 +912,8 @@ void CompareImage(const wxImageHandler& handler, const wxImage& image, return; } - if (type == wxBITMAP_TYPE_JPEG /* skip lossy JPEG */ - || type == wxBITMAP_TYPE_TIF) + if (type == wxBITMAP_TYPE_JPEG /* skip lossy JPEG */) { - /* - TIFF is skipped because the memory stream can't be loaded. Libtiff - looks for a TIFF directory at offset 120008 while the memory - stream size is only 120008 bytes (when saving as a file - the file size is 120280 bytes). - */ return; } From 7a10e465ca4f5dacd1b59b4fb4d8318b8ccb0b0b Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 01:08:36 +0000 Subject: [PATCH 024/167] Improved saving of TIFF monochrome images. When reducing an RGB image to black and white any non-black pixel was treated as white resulting in mostly white images. Set the threshold to 127 instead to improve the looks of saved monochrome TIFF images. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68777 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 59b7fb9b43..a10940d63c 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -658,7 +658,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo uint8 reverse = 0; for ( int bp = 0; bp < 8; bp++ ) { - if ( ptr[column*24 + bp*3] > 0 ) + if ( ptr[column*24 + bp*3] > 127 ) { // check only red as this is sufficient reverse = (uint8)(reverse | 128 >> bp); From 6f54591185514725f14721bb873926602f5d42ee Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 01:13:16 +0000 Subject: [PATCH 025/167] improved wxImage documentation. moved description of wxIMAGE_OPTION_GIF_COMMENT from wxImage::GetOptionInt documentation to wxImage::GetOption because the value of the GIF option is a string, not int. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68779 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- interface/wx/image.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/wx/image.h b/interface/wx/image.h index cdeba80f58..a6cf2769cf 100644 --- a/interface/wx/image.h +++ b/interface/wx/image.h @@ -1084,10 +1084,16 @@ public: /** Gets a user-defined string-valued option. - Currently the only defined string option is + Generic options: @li @c wxIMAGE_OPTION_FILENAME: The name of the file from which the image was loaded. + Options specific to wxGIFHandler: + @li @c wxIMAGE_OPTION_GIF_COMMENT: The comment text that is read from + or written to the GIF file. In an animated GIF each frame can have + its own comment. If there is only a comment in the first frame of + a GIF it will not be repeated in other frames. + @param name The name of the option, case-insensitive. @return @@ -1162,12 +1168,6 @@ public: the resulting PNG file. Use this option if your application produces images with small size variation. - Options specific to wxGIFHandler: - @li @c wxIMAGE_OPTION_GIF_COMMENT: The comment text that is read from - or written to the GIF file. In an animated GIF each frame can have - its own comment. If there is only a comment in the first frame of - a GIF it will not be repeated in other frames. - @param name The name of the option, case-insensitive. @return From d65172db909ddd431a9f303949dadc57f6ac16fb Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 01:19:21 +0000 Subject: [PATCH 026/167] Renamed the options specific to the TIFF handler. The loading/saving options that are specific for TIFF were in the form of wxIMAGE_OPTION_ while all other non-generic options use the form wxIMAGE_OPTION__. Renamed the TIFF options to the form wxIMAGE_OPTION_TIFF_ and kept the old names for backwards compatibility. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68780 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/imagtiff.h | 14 ++++++++++---- src/common/imagtiff.cpp | 12 ++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/include/wx/imagtiff.h b/include/wx/imagtiff.h index 3021a61e4a..19d1cf1c73 100644 --- a/include/wx/imagtiff.h +++ b/include/wx/imagtiff.h @@ -22,10 +22,16 @@ #include "wx/versioninfo.h" // defines for wxImage::SetOption -#define wxIMAGE_OPTION_BITSPERSAMPLE wxString(wxT("BitsPerSample")) -#define wxIMAGE_OPTION_SAMPLESPERPIXEL wxString(wxT("SamplesPerPixel")) -#define wxIMAGE_OPTION_COMPRESSION wxString(wxT("Compression")) -#define wxIMAGE_OPTION_IMAGEDESCRIPTOR wxString(wxT("ImageDescriptor")) +#define wxIMAGE_OPTION_TIFF_BITSPERSAMPLE wxString(wxT("BitsPerSample")) +#define wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL wxString(wxT("SamplesPerPixel")) +#define wxIMAGE_OPTION_TIFF_COMPRESSION wxString(wxT("Compression")) +#define wxIMAGE_OPTION_TIFF_IMAGEDESCRIPTOR wxString(wxT("ImageDescriptor")) + +// for backwards compatibility +#define wxIMAGE_OPTION_BITSPERSAMPLE wxIMAGE_OPTION_TIFF_BITSPERSAMPLE +#define wxIMAGE_OPTION_SAMPLESPERPIXEL wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL +#define wxIMAGE_OPTION_COMPRESSION wxIMAGE_OPTION_TIFF_COMPRESSION +#define wxIMAGE_OPTION_IMAGEDESCRIPTOR wxIMAGE_OPTION_TIFF_IMAGEDESCRIPTOR class WXDLLIMPEXP_CORE wxTIFFHandler: public wxImageHandler { diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index a10940d63c..80e9cb3d91 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -444,17 +444,17 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos */ if ( TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp) ) { - image->SetOption(wxIMAGE_OPTION_SAMPLESPERPIXEL, spp); + image->SetOption(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, spp); } if ( TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bpp) ) { - image->SetOption(wxIMAGE_OPTION_BITSPERSAMPLE, bpp); + image->SetOption(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, bpp); } if ( TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compression) ) { - image->SetOption(wxIMAGE_OPTION_COMPRESSION, compression); + image->SetOption(wxIMAGE_OPTION_TIFF_COMPRESSION, compression); } // Set the resolution unit. @@ -587,15 +587,15 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo } - int spp = image->GetOptionInt(wxIMAGE_OPTION_SAMPLESPERPIXEL); + int spp = image->GetOptionInt(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL); if ( !spp ) spp = 3; - int bpp = image->GetOptionInt(wxIMAGE_OPTION_BITSPERSAMPLE); + int bpp = image->GetOptionInt(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE); if ( !bpp ) bpp = 8; - int compression = image->GetOptionInt(wxIMAGE_OPTION_COMPRESSION); + int compression = image->GetOptionInt(wxIMAGE_OPTION_TIFF_COMPRESSION); if ( !compression ) { // we can't use COMPRESSION_LZW because current version of libtiff From 096c930c169aec8a027a065163cf78e3e46b224c Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 01:31:07 +0000 Subject: [PATCH 027/167] No code changes. Renamed variable bpp (bits per pixel) in TIFF handler to what it actually represents: bps (bits per sample). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68781 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 80e9cb3d91..3d8c102821 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -437,7 +437,7 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos } - uint16 spp, bpp, compression; + uint16 spp, bps, compression; /* Read some baseline TIFF tags which helps when re-saving a TIFF to be similar to the original image. @@ -447,9 +447,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos image->SetOption(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, spp); } - if ( TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bpp) ) + if ( TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps) ) { - image->SetOption(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, bpp); + image->SetOption(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, bps); } if ( TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compression) ) @@ -591,9 +591,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo if ( !spp ) spp = 3; - int bpp = image->GetOptionInt(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE); - if ( !bpp ) - bpp = 8; + int bps = image->GetOptionInt(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE); + if ( !bps ) + bps = 8; int compression = image->GetOptionInt(wxIMAGE_OPTION_TIFF_COMPRESSION); if ( !compression ) @@ -606,20 +606,20 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo } TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp); - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bpp); - TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, spp*bpp == 1 ? PHOTOMETRIC_MINISBLACK + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, spp*bps == 1 ? PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB); TIFFSetField(tif, TIFFTAG_COMPRESSION, compression); - // scanlinesize if determined by spp and bpp - tsize_t linebytes = (tsize_t)image->GetWidth() * spp * bpp / 8; + // scanlinesize if determined by spp and bps + tsize_t linebytes = (tsize_t)image->GetWidth() * spp * bps / 8; - if ( (image->GetWidth() % 8 > 0) && (spp * bpp < 8) ) + if ( (image->GetWidth() % 8 > 0) && (spp * bps < 8) ) linebytes+=1; unsigned char *buf; - if (TIFFScanlineSize(tif) > linebytes || (spp * bpp < 24)) + if (TIFFScanlineSize(tif) > linebytes || (spp * bps < 24)) { buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif)); if (!buf) @@ -646,7 +646,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo { if ( buf ) { - if ( spp * bpp > 1 ) + if ( spp * bps > 1 ) { // color image memcpy(buf, ptr, image->GetWidth()); From 0e11090ef6cd6cf68a7ee521feb126006a70e368 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 02:00:25 +0000 Subject: [PATCH 028/167] Fixed crash when saving as a monochrome TIFF image with incomplete options set. When setting only wxIMAGE_OPTION_TIFF_BITSPERSAMPLE to 1 the used samples per pixel (wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL) would still be set to 3. This is invalid and confuses libtiff, resulting in a crash ("possible heap corruption" during _TIFFfree using WinXP+MSVC8). Set the used samples per pixel to 1 explicitly in cases where only bits per sample is set to 1. Added a unit test to check for this problem (and verify the bits per sample from the saved image is indeed 1). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68782 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 8 ++++++++ tests/image/image.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 3d8c102821..b3209d39f9 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -593,7 +593,15 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo int bps = image->GetOptionInt(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE); if ( !bps ) + { bps = 8; + } + else if (bps == 1) + { + // One bit per sample combined with 3 samples per pixel is + // not allowed and crashes libtiff. + spp = 1; + } int compression = image->GetOptionInt(wxIMAGE_OPTION_TIFF_COMPRESSION); if ( !compression ) diff --git a/tests/image/image.cpp b/tests/image/image.cpp index 22384f5e1f..010bc1d278 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -73,6 +73,7 @@ private: CPPUNIT_TEST( CompareLoadedImage ); CPPUNIT_TEST( CompareSavedImage ); CPPUNIT_TEST( SavePNG ); + CPPUNIT_TEST( SaveTIFF ); CPPUNIT_TEST( SaveAnimatedGIF ); CPPUNIT_TEST( ReadCorruptedTGA ); CPPUNIT_TEST( GIFComment ); @@ -87,6 +88,7 @@ private: void CompareLoadedImage(); void CompareSavedImage(); void SavePNG(); + void SaveTIFF(); void SaveAnimatedGIF(); void ReadCorruptedTGA(); void GIFComment(); @@ -1088,6 +1090,33 @@ void ImageTestCase::SavePNG() } +static void TestTIFFImage(const wxString& option, int value) +{ + wxImage image("horse.png"); + + wxMemoryOutputStream memOut; + image.SetOption(option, value); + + CPPUNIT_ASSERT(image.SaveFile(memOut, wxBITMAP_TYPE_TIF)); + + wxMemoryInputStream memIn(memOut); + CPPUNIT_ASSERT(memIn.IsOk()); + + wxImage savedImage(memIn); + CPPUNIT_ASSERT(savedImage.IsOk()); + + WX_ASSERT_EQUAL_MESSAGE(("While checking for option %s", option), + true, savedImage.HasOption(option)); + + WX_ASSERT_EQUAL_MESSAGE(("While testing for %s", option), + value, savedImage.GetOptionInt(option)); +} + +void ImageTestCase::SaveTIFF() +{ + TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1); +} + void ImageTestCase::SaveAnimatedGIF() { #if wxUSE_PALETTE From 7f77b25ea8cad399e71bfce5514df6294cce1f45 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 02:27:11 +0000 Subject: [PATCH 029/167] Changed TIFF handler's monochrome conversion to look at the green channel instead of red. It's common when reducing a coloured image to greyscale or black and white to give the green channel more significance. Since we're only looking at a single channel use the green one instead of red. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68783 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index b3209d39f9..e852fc00f0 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -666,9 +666,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo uint8 reverse = 0; for ( int bp = 0; bp < 8; bp++ ) { - if ( ptr[column*24 + bp*3] > 127 ) + if ( ptr[column*24 + bp*3 + 1] > 127 ) { - // check only red as this is sufficient + // check only green as this is sufficient reverse = (uint8)(reverse | 128 >> bp); } } From 8e28cc4701896761cd2c306525be2a31eb622cf4 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 02:35:48 +0000 Subject: [PATCH 030/167] Added support for saving greyscale TIFF images. When saving with a samples per pixel value of 1 the TIFF handler still treated the image as RGB, resulting in corrupted images. Handle the greyscale case and added a unit test for it. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68784 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 7 +++++++ tests/image/image.cpp | 1 + 2 files changed, 8 insertions(+) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index e852fc00f0..d8d449c5cf 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -659,6 +659,13 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo // color image memcpy(buf, ptr, image->GetWidth()); } + else if (spp * bps == 8) // greyscale image + { + for ( int column = 0; column < linebytes; column++ ) + { + buf[column] = ptr[column*3 + 1]; + } + } else // black and white image { for ( int column = 0; column < linebytes; column++ ) diff --git a/tests/image/image.cpp b/tests/image/image.cpp index 010bc1d278..9135e433b9 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -1115,6 +1115,7 @@ static void TestTIFFImage(const wxString& option, int value) void ImageTestCase::SaveTIFF() { TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1); + TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 1); } void ImageTestCase::SaveAnimatedGIF() From fc695138b415c96a5b8a5a58086e5c393b4a349e Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 03:47:40 +0000 Subject: [PATCH 031/167] Added option to TIFF handler for specifying the photometric interpretation. Added option wxIMAGE_OPTION_TIFF_PHOTOMETRIC for reading and writing TIFF images. This is mostly for being able to distinguish between PHOTOMETRIC_MINISBLACK (chocolate flavour) and PHOTOMETRIC_MINISWHITE (vanilla) as currently the flavour used was fixed. It applies to greyscale as well as black and white images. Added unit tests to verify the written photometric value. Also see #13194. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68785 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/imagtiff.h | 1 + src/common/imagtiff.cpp | 41 +++++++++++++++++++++++++++++++++++------ tests/image/image.cpp | 2 ++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/include/wx/imagtiff.h b/include/wx/imagtiff.h index 19d1cf1c73..f1f4f74c6f 100644 --- a/include/wx/imagtiff.h +++ b/include/wx/imagtiff.h @@ -25,6 +25,7 @@ #define wxIMAGE_OPTION_TIFF_BITSPERSAMPLE wxString(wxT("BitsPerSample")) #define wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL wxString(wxT("SamplesPerPixel")) #define wxIMAGE_OPTION_TIFF_COMPRESSION wxString(wxT("Compression")) +#define wxIMAGE_OPTION_TIFF_PHOTOMETRIC wxString(wxT("Photometric")) #define wxIMAGE_OPTION_TIFF_IMAGEDESCRIPTOR wxString(wxT("ImageDescriptor")) // for backwards compatibility diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index d8d449c5cf..e4458e3f98 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -437,6 +437,8 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos } + image->SetOption(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, photometric); + uint16 spp, bps, compression; /* Read some baseline TIFF tags which helps when re-saving a TIFF @@ -603,6 +605,27 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo spp = 1; } + int photometric = PHOTOMETRIC_RGB; + + if ( image->HasOption(wxIMAGE_OPTION_TIFF_PHOTOMETRIC) ) + { + photometric = image->GetOptionInt(wxIMAGE_OPTION_TIFF_PHOTOMETRIC); + if (photometric == PHOTOMETRIC_MINISWHITE + || photometric == PHOTOMETRIC_MINISBLACK) + { + // either b/w or greyscale + spp = 1; + } + } + else if (spp == 1) + { + photometric = PHOTOMETRIC_MINISBLACK; + } + + const bool isColouredImage = (spp > 1) + && (photometric != PHOTOMETRIC_MINISWHITE) + && (photometric != PHOTOMETRIC_MINISBLACK); + int compression = image->GetOptionInt(wxIMAGE_OPTION_TIFF_COMPRESSION); if ( !compression ) { @@ -615,8 +638,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); - TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, spp*bps == 1 ? PHOTOMETRIC_MINISBLACK - : PHOTOMETRIC_RGB); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(tif, TIFFTAG_COMPRESSION, compression); // scanlinesize if determined by spp and bps @@ -627,7 +649,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo unsigned char *buf; - if (TIFFScanlineSize(tif) > linebytes || (spp * bps < 24)) + if (TIFFScanlineSize(tif) > linebytes || !isColouredImage) { buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif)); if (!buf) @@ -649,12 +671,13 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,TIFFDefaultStripSize(tif, (uint32) -1)); + const bool minIsWhite = (photometric == PHOTOMETRIC_MINISWHITE); unsigned char *ptr = image->GetData(); for ( int row = 0; row < image->GetHeight(); row++ ) { if ( buf ) { - if ( spp * bps > 1 ) + if (isColouredImage) { // color image memcpy(buf, ptr, image->GetWidth()); @@ -663,7 +686,13 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo { for ( int column = 0; column < linebytes; column++ ) { - buf[column] = ptr[column*3 + 1]; + uint8 value = ptr[column*3 + 1]; + if (minIsWhite) + { + value = 255 - value; + } + + buf[column] = value; } } else // black and white image @@ -673,7 +702,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo uint8 reverse = 0; for ( int bp = 0; bp < 8; bp++ ) { - if ( ptr[column*24 + bp*3 + 1] > 127 ) + if ( (ptr[column*24 + bp*3 + 1] <=127) == minIsWhite ) { // check only green as this is sufficient reverse = (uint8)(reverse | 128 >> bp); diff --git a/tests/image/image.cpp b/tests/image/image.cpp index 9135e433b9..0350dcbfa9 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -1116,6 +1116,8 @@ void ImageTestCase::SaveTIFF() { TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1); TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 1); + TestTIFFImage(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, 0/*PHOTOMETRIC_MINISWHITE*/); + TestTIFFImage(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, 1/*PHOTOMETRIC_MINISBLACK*/); } void ImageTestCase::SaveAnimatedGIF() From 2453ceee20aab72c214ec26b4757c4ac6d09cfbd Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 03:50:45 +0000 Subject: [PATCH 032/167] Use a default photometric interpretation value of PHOTOMETRIC_MINISWHITE instead of PHOTOMETRIC_MINISBLACK for greyscale and b/w TIFF images. Closes #13194. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68786 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/imagtiff.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index e4458e3f98..40083e6bab 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -619,7 +619,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo } else if (spp == 1) { - photometric = PHOTOMETRIC_MINISBLACK; + photometric = PHOTOMETRIC_MINISWHITE; } const bool isColouredImage = (spp > 1) From 659185ff8057016daa5ffd462981df4db112e805 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 03:57:06 +0000 Subject: [PATCH 033/167] Documented wxIMAGE_OPTION_TIFF_* options that are currently in use. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68787 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- interface/wx/image.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/interface/wx/image.h b/interface/wx/image.h index a6cf2769cf..7c5dcd6b2f 100644 --- a/interface/wx/image.h +++ b/interface/wx/image.h @@ -1168,6 +1168,39 @@ public: the resulting PNG file. Use this option if your application produces images with small size variation. + Options specific to wxTIFFHandler: + @li @c wxIMAGE_OPTION_TIFF_BITSPERSAMPLE: Number of bits per + sample (channel). Currently values of 1 and 8 are supported. A + value of 1 results in a black and white image. A value of 8 (the + default) can mean greyscale or RGB, depending on the value of + @c wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL. + @li @c wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL: Number of samples + (channels) per pixel. Currently values of 1 and 3 are supported. + A value of 1 results in either a greyscale (by default) or black and + white image, depending on the value of + @c wxIMAGE_OPTION_TIFF_BITSPERSAMPLE. A value of 3 (the default) + will result in an RGB image. + @li @c wxIMAGE_OPTION_TIFF_COMPRESSION: Compression type. By default + it is set to 1 (COMPRESSION_NONE). Typical other values are + 5 (COMPRESSION_LZW) and 7 (COMPRESSION_JPEG). See tiff.h for more + options. + @li @c wxIMAGE_OPTION_TIFF_PHOTOMETRIC: Specifies the photometric + interpretation. By default it is set to 2 (PHOTOMETRIC_RGB) for RGB + images and 0 (PHOTOMETRIC_MINISWHITE) for greyscale or black and + white images. It can also be set to 1 (PHOTOMETRIC_MINISBLACK) to + treat the lowest value as black and highest as white. + If you want a greyscale image it is also sufficient to only specify + @c wxIMAGE_OPTION_TIFF_PHOTOMETRIC and set it to either + PHOTOMETRIC_MINISWHITE or PHOTOMETRIC_MINISBLACK. The other values + are taken care of. + + @note + Be careful when combining the options @c wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, + @c wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, and @c wxIMAGE_OPTION_TIFF_PHOTOMETRIC. + While some measures are taken to prevent illegal combinations and/or + values, it is still easy to abuse them and come up with invalid + results in the form of either corrupted images or crashes. + @param name The name of the option, case-insensitive. @return From 409fe759e1b605514eabcddfb546dc876b9a9161 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Fri, 19 Aug 2011 16:10:07 +0000 Subject: [PATCH 034/167] Fixed failing test in ImageTestCase for builds made with makefiles. The recently added BMP images in tests/image/ were not being copied. Added them to test.bkl and regenerated makefiles. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68791 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- tests/Makefile.in | 16 ++++++++++++++-- tests/makefile.bcc | 6 +++++- tests/makefile.gcc | 8 ++++++-- tests/makefile.vc | 6 +++++- tests/makefile.wat | 6 +++++- tests/test.bkl | 8 ++++++++ 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/tests/Makefile.in b/tests/Makefile.in index 26ae782b00..396d64ab28 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -338,7 +338,7 @@ COND_wxUSE_REGEX_builtin___LIB_REGEX_p = \ ### Targets: ### -all: test$(EXEEXT) $(__test_gui___depname) $(__test_gui_bundle___depname) data fr +all: test$(EXEEXT) $(__test_gui___depname) $(__test_gui_bundle___depname) data data-images fr install: @@ -406,6 +406,18 @@ data: esac; \ done +data-images: + @mkdir -p image + @for f in horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp; do \ + if test ! -f image/$$f -a ! -d image/$$f ; \ + then x=yep ; \ + else x=`find $(srcdir)/image/$$f -newer image/$$f -print` ; \ + fi; \ + case "$$x" in ?*) \ + cp -pRf $(srcdir)/image/$$f image ;; \ + esac; \ + done + fr: @mkdir -p ./intl/fr @for f in internat.po internat.mo; do \ @@ -925,4 +937,4 @@ failtest: # Include dependency info, if present: @IF_GNU_MAKE@-include ./.deps/*.d -.PHONY: all install uninstall clean distclean test_gui_bundle data fr +.PHONY: all install uninstall clean distclean test_gui_bundle data data-images fr diff --git a/tests/makefile.bcc b/tests/makefile.bcc index 812e939fae..d1c4d4f5b0 100644 --- a/tests/makefile.bcc +++ b/tests/makefile.bcc @@ -421,7 +421,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\test.exe $(__test_gui___depname) data fr +all: $(OBJS)\test.exe $(__test_gui___depname) data data-images fr clean: -if exist $(OBJS)\*.obj del $(OBJS)\*.obj @@ -456,6 +456,10 @@ data: if not exist $(OBJS) mkdir $(OBJS) for %f in (horse.ani horse.bmp horse.cur horse.gif horse.ico horse.jpg horse.pcx horse.png horse.pnm horse.tga horse.tif horse.xpm) do if not exist $(OBJS)\%f copy .\%f $(OBJS) +data-images: + if not exist image mkdir image + for %f in (horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp) do if not exist image\%f copy .\image\%f image + fr: if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr for %f in (internat.po internat.mo) do if not exist $(OBJS)\intl\fr\%f copy .\intl\fr\%f $(OBJS)\intl\fr diff --git a/tests/makefile.gcc b/tests/makefile.gcc index 49ea23cddd..cdcc61af59 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -417,7 +417,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\test.exe $(__test_gui___depname) data fr +all: $(OBJS)\test.exe $(__test_gui___depname) data data-images fr clean: -if exist $(OBJS)\*.o del $(OBJS)\*.o @@ -437,6 +437,10 @@ data: if not exist $(OBJS) mkdir $(OBJS) for %%f in (horse.ani horse.bmp horse.cur horse.gif horse.ico horse.jpg horse.pcx horse.png horse.pnm horse.tga horse.tif horse.xpm) do if not exist $(OBJS)\%%f copy .\%%f $(OBJS) +data-images: + if not exist image mkdir image + for %%f in (horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp) do if not exist image\%%f copy .\image\%%f image + fr: if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr for %%f in (internat.po internat.mo) do if not exist $(OBJS)\intl\fr\%%f copy .\intl\fr\%%f $(OBJS)\intl\fr @@ -933,7 +937,7 @@ $(OBJS)\test_gui_setsize.o: ./window/setsize.cpp $(OBJS)\test_gui_xrctest.o: ./xml/xrctest.cpp $(CXX) -c -o $@ $(TEST_GUI_CXXFLAGS) $(CPPDEPS) $< -.PHONY: all clean data fr +.PHONY: all clean data data-images fr SHELL := $(COMSPEC) diff --git a/tests/makefile.vc b/tests/makefile.vc index 91f4734924..86c782f582 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -553,7 +553,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\test.exe $(__test_gui___depname) data fr +all: $(OBJS)\test.exe $(__test_gui___depname) data data-images fr clean: -if exist $(OBJS)\*.obj del $(OBJS)\*.obj @@ -582,6 +582,10 @@ data: if not exist $(OBJS) mkdir $(OBJS) for %f in (horse.ani horse.bmp horse.cur horse.gif horse.ico horse.jpg horse.pcx horse.png horse.pnm horse.tga horse.tif horse.xpm) do if not exist $(OBJS)\%f copy .\%f $(OBJS) +data-images: + if not exist image mkdir image + for %f in (horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp) do if not exist image\%f copy .\image\%f image + fr: if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr for %f in (internat.po internat.mo) do if not exist $(OBJS)\intl\fr\%f copy .\intl\fr\%f $(OBJS)\intl\fr diff --git a/tests/makefile.wat b/tests/makefile.wat index e566570d79..51549e53ed 100644 --- a/tests/makefile.wat +++ b/tests/makefile.wat @@ -455,7 +455,7 @@ $(OBJS) : ### Targets: ### -all : .SYMBOLIC $(OBJS)\test.exe $(__test_gui___depname) data fr +all : .SYMBOLIC $(OBJS)\test.exe $(__test_gui___depname) data data-images fr clean : .SYMBOLIC -if exist $(OBJS)\*.obj del $(OBJS)\*.obj @@ -496,6 +496,10 @@ data : .SYMBOLIC if not exist $(OBJS) mkdir $(OBJS) for %f in (horse.ani horse.bmp horse.cur horse.gif horse.ico horse.jpg horse.pcx horse.png horse.pnm horse.tga horse.tif horse.xpm) do if not exist $(OBJS)\%f copy .\%f $(OBJS) +data-images : .SYMBOLIC + if not exist image mkdir image + for %f in (horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp) do if not exist image\%f copy .\image\%f image + fr : .SYMBOLIC if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr for %f in (internat.po internat.mo) do if not exist $(OBJS)\intl\fr\%f copy .\intl\fr\%f $(OBJS)\intl\fr diff --git a/tests/test.bkl b/tests/test.bkl index 344abee419..ba5bf00ae7 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -230,6 +230,14 @@ horse.pcx horse.png horse.pnm horse.tga horse.tif horse.xpm + + $(SRCDIR)/image + image + horse_grey.bmp horse_grey_flipped.bmp + horse_rle4.bmp horse_rle4_flipped.bmp + horse_rle8.bmp horse_rle8_flipped.bmp + +