[haiku-commits] r37118 - haiku/trunk/src/apps/showimage

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 12 Jun 2010 19:03:53 +0200 (CEST)

Author: stippi
Date: 2010-06-12 19:03:53 +0200 (Sat, 12 Jun 2010)
New Revision: 37118
Changeset: http://dev.haiku-os.org/changeset/37118/haiku

Modified:
   haiku/trunk/src/apps/showimage/ShowImageApp.cpp
   haiku/trunk/src/apps/showimage/ShowImageView.cpp
   haiku/trunk/src/apps/showimage/ShowImageView.h
Log:
 * Fixed storage of image data in the system clipboard. According to the
   comments in the code, different programs do it differently. However, I
   believe we should follow the BeBook documentation. This is the method which
   WonderBrush uses as well, and that one had been tested with other apps like
   Refraction. Potentially, copy&paste could work across GoBe Productive now
   also, but I didn't test.
 * Handle the case where the selection bitmap that gets restored from the
   clipboard has a bounds rectangle with an offset. Use this offset as an
   alternative to the "be:location" hack.
 * Fix the drag bitmap to be semi-transparent on Haiku. B_OP_SELECT does not
   affect the alpha channel on Haiku like it apparently did on BeOS, though
   I am not inclined to change that behavior.
 * Fixed some coding style violations, but tried to mix as little cleanup as
   possible.


Modified: haiku/trunk/src/apps/showimage/ShowImageApp.cpp
===================================================================
--- haiku/trunk/src/apps/showimage/ShowImageApp.cpp     2010-06-12 16:04:49 UTC 
(rev 37117)
+++ haiku/trunk/src/apps/showimage/ShowImageApp.cpp     2010-06-12 17:03:53 UTC 
(rev 37118)
@@ -226,11 +226,8 @@
        if (be_clipboard->Lock()) {
                BMessage* clip = be_clipboard->Data();
                if (clip != NULL) {
-                       BString className;
-                       if (clip->FindString("class", &className) == B_OK) {
-                               if (className == "BBitmap")
-                                       dataAvailable = true;
-                       }
+                       dataAvailable = clip->HasMessage("image/bitmap")
+                               || clip->HasMessage("image/x-be-bitmap");
                }
 
                be_clipboard->Unlock();

Modified: haiku/trunk/src/apps/showimage/ShowImageView.cpp
===================================================================
--- haiku/trunk/src/apps/showimage/ShowImageView.cpp    2010-06-12 16:04:49 UTC 
(rev 37117)
+++ haiku/trunk/src/apps/showimage/ShowImageView.cpp    2010-06-12 17:03:53 UTC 
(rev 37118)
@@ -189,7 +189,7 @@
        fDocumentCount(1),
        fBitmap(NULL),
        fDisplayBitmap(NULL),
-       fSelBitmap(NULL),
+       fSelectionBitmap(NULL),
        fZoom(1.0),
        fScaleBilinear(true),
        fScaler(NULL),
@@ -475,8 +475,8 @@
 void
 ShowImageView::_DeleteSelectionBitmap()
 {
-       delete fSelBitmap;
-       fSelBitmap = NULL;
+       delete fSelectionBitmap;
+       fSelectionBitmap = NULL;
 }
 
 
@@ -1007,11 +1007,12 @@
                _DrawCaption();
 
        if (_HasSelection()) {
-               if (fSelBitmap) {
-                       BRect srcBits, destRect;
-                       _GetSelMergeRects(srcBits, destRect);
-                       destRect = _ImageToView(destRect);
-                       DrawBitmap(fSelBitmap, srcBits, destRect);
+               if (fSelectionBitmap != NULL) {
+                       BRect srcRect;
+                       BRect dstRect;
+                       _GetSelectionMergeRects(srcRect, dstRect);
+                       dstRect = _ImageToView(dstRect);
+                       DrawBitmap(fSelectionBitmap, srcRect, dstRect);
                }
                _DrawSelectionBox();
        }
@@ -1098,7 +1099,8 @@
                rect.bottom = floorf((rect.bottom + 1.0) * fZoom - 1.0);
        }
        BView view(rect, NULL, B_FOLLOW_NONE, B_WILL_DRAW);
-       BBitmap *bitmap = new(nothrow) BBitmap(rect, hasAlpha ? B_RGBA32 : 
fBitmap->ColorSpace(), true);
+       BBitmap* bitmap = new(nothrow) BBitmap(rect, hasAlpha ? B_RGBA32
+               : fBitmap->ColorSpace(), true);
        if (bitmap == NULL || !bitmap->IsValid()) {
                delete bitmap;
                return NULL;
@@ -1106,15 +1108,33 @@
 
        if (bitmap->Lock()) {
                bitmap->AddChild(&view);
-               if (fSelBitmap)
-                       view.DrawBitmap(fSelBitmap, fSelBitmap->Bounds(), rect);
-               else
+#ifdef __HAIKU__
+               // On Haiku, B_OP_SUBSTRACT does not affect alpha like it did 
on BeOS.
+               // Don't know if it's better to fix it or not (stippi).
+               if (hasAlpha) {
+                       view.SetHighColor(0, 0, 0, 0);
+                       view.FillRect(view.Bounds());
+                       view.SetDrawingMode(B_OP_ALPHA);
+                       view.SetBlendingMode(B_CONSTANT_ALPHA, 
B_ALPHA_COMPOSITE);
+                       view.SetHighColor(0, 0, 0, alpha);
+               }
+               if (fSelectionBitmap) {
+                       view.DrawBitmap(fSelectionBitmap,
+                               
fSelectionBitmap->Bounds().OffsetToCopy(B_ORIGIN), rect);
+               } else
                        view.DrawBitmap(fBitmap, fCopyFromRect, rect);
+#else
+               if (fSelectionBitmap) {
+                       view.DrawBitmap(fSelectionBitmap,
+                               
fSelectionBitmap->Bounds().OffsetToCopy(B_ORIGIN), rect);
+               } else
+                       view.DrawBitmap(fBitmap, fCopyFromRect, rect);
                if (hasAlpha) {
                        view.SetDrawingMode(B_OP_SUBTRACT);
-                       view.SetHighColor(0, 0, 0, 255-alpha);
+                       view.SetHighColor(0, 0, 0, 255 - alpha);
                        view.FillRect(rect, B_SOLID_HIGH);
                }
+#endif
                view.Sync();
                bitmap->RemoveChild(&view);
                bitmap->Unlock();
@@ -1383,47 +1403,41 @@
 
 
 void
-ShowImageView::_GetMergeRects(BBitmap *merge, BRect selection, BRect &srcBits,
-       BRect &destRect)
+ShowImageView::_GetMergeRects(BBitmap* merge, BRect selection, BRect& srcRect,
+       BRect& dstRect)
 {
-       destRect = selection;
-       _ConstrainToImage(destRect);
+       // Constrain dstRect to target image size and apply the same edge 
offsets
+       // to the srcRect.
 
-       srcBits = selection;
-       if (srcBits.left < 0)
-               srcBits.left = -(srcBits.left);
-       else
-               srcBits.left = 0;
+       dstRect = selection;
 
-       if (srcBits.top < 0)
-               srcBits.top = -(srcBits.top);
-       else
-               srcBits.top = 0;
+       BRect clippedDstRect(dstRect);
+       _ConstrainToImage(clippedDstRect);
 
-       if (srcBits.right > fBitmap->Bounds().right)
-               srcBits.right = srcBits.left + destRect.Width();
-       else
-               srcBits.right = merge->Bounds().right;
+       srcRect = merge->Bounds().OffsetToCopy(B_ORIGIN);
 
-       if (srcBits.bottom > fBitmap->Bounds().bottom)
-               srcBits.bottom = srcBits.top + destRect.Height();
-       else
-               srcBits.bottom = merge->Bounds().bottom;
+       srcRect.left += clippedDstRect.left - dstRect.left;
+       srcRect.top += clippedDstRect.top - dstRect.top;
+       srcRect.right += clippedDstRect.right - dstRect.right;
+       srcRect.bottom += clippedDstRect.bottom - dstRect.bottom;
+
+       dstRect = clippedDstRect;
 }
 
 
 void
-ShowImageView::_GetSelMergeRects(BRect &srcBits, BRect &destRect)
+ShowImageView::_GetSelectionMergeRects(BRect& srcRect, BRect& dstRect)
 {
-       _GetMergeRects(fSelBitmap, fSelectionRect, srcBits, destRect);
+       _GetMergeRects(fSelectionBitmap, fSelectionRect, srcRect, dstRect);
 }
 
 
 void
-ShowImageView::_MergeWithBitmap(BBitmap *merge, BRect selection)
+ShowImageView::_MergeWithBitmap(BBitmap* merge, BRect selection)
 {
        BView view(fBitmap->Bounds(), NULL, B_FOLLOW_NONE, B_WILL_DRAW);
-       BBitmap *bitmap = new(nothrow) BBitmap(fBitmap->Bounds(), 
fBitmap->ColorSpace(), true);
+       BBitmap* bitmap = new(nothrow) BBitmap(fBitmap->Bounds(),
+               fBitmap->ColorSpace(), true);
        if (bitmap == NULL || !bitmap->IsValid()) {
                delete bitmap;
                return;
@@ -1432,9 +1446,10 @@
        if (bitmap->Lock()) {
                bitmap->AddChild(&view);
                view.DrawBitmap(fBitmap, fBitmap->Bounds());
-               BRect srcBits, destRect;
-               _GetMergeRects(merge, selection, srcBits, destRect);
-               view.DrawBitmap(merge, srcBits, destRect);
+               BRect srcRect;
+               BRect dstRect;
+               _GetMergeRects(merge, selection, srcRect, dstRect);
+               view.DrawBitmap(merge, srcRect, dstRect);
 
                view.Sync();
                bitmap->RemoveChild(&view);
@@ -1455,17 +1470,17 @@
        if (!_HasSelection())
                return;
 
-       if (!fSelBitmap) {
-               // Even though the merge will not change
-               // the background image, I still need to save
-               // some undo information here
+       if (fSelectionBitmap == NULL) {
+               // Even though the merge will not change the background image,
+               // undo information still needs to be saved here.
                fUndo.SetTo(fSelectionRect, NULL, _CopySelection());
                return;
        }
 
        // Merge selection with background
-       fUndo.SetTo(fSelectionRect, _CopyFromRect(fSelectionRect), 
_CopySelection());
-       _MergeWithBitmap(fSelBitmap, fSelectionRect);
+       fUndo.SetTo(fSelectionRect, _CopyFromRect(fSelectionRect),
+               _CopySelection());
+       _MergeWithBitmap(fSelectionBitmap, fSelectionRect);
 }
 
 
@@ -1481,8 +1496,8 @@
 
        if (_HasSelection() && fSelectionRect.Contains(point)
                && (buttons & (B_PRIMARY_MOUSE_BUTTON | 
B_SECONDARY_MOUSE_BUTTON))) {
-               if (!fSelBitmap)
-                       fSelBitmap = _CopySelection();
+               if (!fSelectionBitmap)
+                       fSelectionBitmap = _CopySelection();
 
                BPoint sourcePoint = point;
                _BeginDrag(sourcePoint);
@@ -1966,14 +1981,14 @@
        BBitmap *undoSelection;
        undoSelection = fUndo.GetSelectionBitmap();
                // NOTE: ShowImageView is responsible for deleting this bitmap
-               // (Which it will, as it would with a fSelBitmap that it 
allocated itself)
+               // (Which it will, as it would with a fSelectionBitmap that it 
allocated itself)
        if (!undoSelection)
                _SetHasSelection(false);
        else {
                fCopyFromRect = BRect();
                fSelectionRect = fUndo.GetRect();
                _SetHasSelection(true);
-               fSelBitmap = undoSelection;
+               fSelectionBitmap = undoSelection;
        }
 
        fUndo.Undo(undoneSelRect, NULL, undoneSelection);
@@ -2020,7 +2035,7 @@
                return;
 
        BRect rect = fSelectionRect;
-       bool cutBackground = (fSelBitmap) ? false : true;
+       bool cutBackground = (fSelectionBitmap) ? false : true;
        BBitmap* selection = _CopySelection();
        BBitmap* restore = NULL;
 
@@ -2051,48 +2066,60 @@
 
 
 status_t
-ShowImageView::_PasteBitmap(BBitmap *bitmap, BPoint point)
+ShowImageView::_PasteBitmap(BBitmap* bitmap, BPoint point)
 {
-       if (bitmap && bitmap->IsValid()) {
-               _MergeSelection();
+       if (bitmap == NULL || !bitmap->IsValid())
+               return B_BAD_VALUE;
 
-               fCopyFromRect = BRect();
-               fSelectionRect = bitmap->Bounds();
-               _SetHasSelection(true);
-               fSelBitmap = bitmap;
+       _MergeSelection();
 
-               BRect offsetRect = fSelectionRect;
-               offsetRect.OffsetBy(point);
-               if (fBitmap->Bounds().Intersects(offsetRect))
-                       // Move the selection rectangle to desired origin,
-                       // but only if the resulting selection rectangle
-                       // intersects with the background bitmap rectangle
-                       fSelectionRect = offsetRect;
+       fCopyFromRect = BRect();
+       fSelectionRect = bitmap->Bounds().OffsetToCopy(B_ORIGIN);
+       _SetHasSelection(true);
+       delete fSelectionBitmap;
+       fSelectionBitmap = bitmap;
 
-               Invalidate();
-
-               return B_OK;
+       BRect offsetRect(fSelectionRect.OffsetToCopy(point));
+       if (fBitmap->Bounds().Intersects(offsetRect)) {
+               // Move the selection rectangle to desired origin,
+               // but only if the resulting selection rectangle
+               // intersects with the background bitmap rectangle
+               fSelectionRect = offsetRect;
        }
+printf("bitmap: "); bitmap->Bounds().PrintToStream();
+printf("selection: "); fSelectionRect.PrintToStream();
+printf("point: "); point.PrintToStream();
 
-       return B_ERROR;
+       Invalidate();
+
+       return B_OK;
 }
 
 
 void
 ShowImageView::Paste()
 {
-       if (be_clipboard->Lock()) {
-               BMessage *pclip;
-               if ((pclip = be_clipboard->Data()) != NULL) {
-                       BPoint point(0, 0);
-                       pclip->FindPoint("be:location", &point);
-                       BBitmap *pbits;
-                       pbits = dynamic_cast<BBitmap 
*>(BBitmap::Instantiate(pclip));
-                       _PasteBitmap(pbits, point);
+       if (!be_clipboard->Lock())
+               return;
+
+       BMessage* data = be_clipboard->Data();
+       if (data != NULL) {
+               BMessage bitmapArchive;
+               if (data->FindMessage("image/bitmap", &bitmapArchive) == B_OK
+                       || data->FindMessage("image/x-be-bitmap", 
&bitmapArchive)
+                               == B_OK) {
+                       BBitmap* bitmap = dynamic_cast<BBitmap*>(
+                               BBitmap::Instantiate(&bitmapArchive));
+                       if (bitmap != NULL) {
+                               BPoint point;
+                               if (data->FindPoint("be:location", &point) != 
B_OK)
+                                       point = bitmap->Bounds().LeftTop();
+                               _PasteBitmap(bitmap, point);
+                       }
                }
+       }
 
-               be_clipboard->Unlock();
-       }
+       be_clipboard->Unlock();
 }
 
 
@@ -2143,21 +2170,16 @@
        if (data != NULL) {
                BBitmap* bitmap = _CopySelection();
                if (bitmap != NULL) {
-#if 0
-                       // According to BeBook and Becasso, Gobe Productive do 
the
-                       // following. Paste works in Productive, but not in 
Becasso and
-                       // original ShowImage.
-                       BMessage msg(B_OK);
-                               // Becasso uses B_TRANSLATOR_BITMAP, BeBook 
says its unused.
-                       bitmap->Archive(&msg);
-                       data->AddMessage("image/x-be-bitmap", &msg);
-#else
-                       // Original ShowImage performs this.
-                       bitmap->Archive(data);
-                       // original ShowImage uses be:location for insertion 
point
+                       BMessage bitmapArchive;
+                       bitmap->Archive(&bitmapArchive);
+                       // NOTE: Possibly "image/x-be-bitmap" is more correct.
+                       // This works with WonderBrush, though, which in turn 
had been
+                       // tested with other apps.
+                       data->AddMessage("image/bitmap", &bitmapArchive);
                        data->AddPoint("be:location", fSelectionRect.LeftTop());
-#endif
+
                        delete bitmap;
+
                        be_clipboard->Commit();
                }
        }

Modified: haiku/trunk/src/apps/showimage/ShowImageView.h
===================================================================
--- haiku/trunk/src/apps/showimage/ShowImageView.h      2010-06-12 16:04:49 UTC 
(rev 37117)
+++ haiku/trunk/src/apps/showimage/ShowImageView.h      2010-06-12 17:03:53 UTC 
(rev 37118)
@@ -143,7 +143,7 @@
                void _AddToRecentDocuments();
                void _AddWhiteRect(BRect &rect);
                void _GetMergeRects(BBitmap *merge, BRect selection, BRect 
&srcBits, BRect &destRect);
-               void _GetSelMergeRects(BRect &srcBits, BRect &destRect);
+               void _GetSelectionMergeRects(BRect &srcBits, BRect &destRect);
                status_t _SetSelection(const entry_ref *pref, BPoint point);
                status_t _PasteBitmap(BBitmap *bitmap, BPoint point);
                void _MergeWithBitmap(BBitmap *merge, BRect selection);
@@ -211,7 +211,7 @@
                BBitmap *fDisplayBitmap;
                        // the image to be displayed
                        // (== fBitmap if the bitmap can be displayed as is)
-               BBitmap *fSelBitmap;            // the bitmap in the selection
+               BBitmap *fSelectionBitmap;              // the bitmap in the 
selection
                float fZoom;                            // factor to be used to 
display the image
                bool fScaleBilinear;            // use bilinear scaling?
                Scaler* fScaler;                        // holds the scaled 
image if bilinear scaling is enabled


Other related posts: