From 0acb8cc41c3ec7d09e109cf18e7519285be4781d Mon Sep 17 00:00:00 2001 From: Michael Pfeiffer Date: Sun, 17 Dec 2006 18:18:29 +0000 Subject: [PATCH] Variable width2 used at wrong place. Image size too small by one when passed to ResizerWindow. Use fractional arithmetic for aspect ratio calculations to avoid rounding errors. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19542 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/showimage/ResizerWindow.cpp | 28 ++++++++++++++------------ src/apps/showimage/ResizerWindow.h | 9 ++++++--- src/apps/showimage/ShowImageWindow.cpp | 16 ++++++++------- src/apps/showimage/ShowImageWindow.h | 4 ++-- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/apps/showimage/ResizerWindow.cpp b/src/apps/showimage/ResizerWindow.cpp index a142eeed74..8c1f1f7402 100644 --- a/src/apps/showimage/ResizerWindow.cpp +++ b/src/apps/showimage/ResizerWindow.cpp @@ -50,9 +50,10 @@ static const float kLineDistance = 5; static const float kHorizontalIndent = 10; static const float kVerticalIndent = 10; -ResizerWindow::ResizerWindow(BMessenger target, float width, float height) +ResizerWindow::ResizerWindow(BMessenger target, int32 width, int32 height) : BWindow(BRect(100, 100, 300, 300), "Resize", B_FLOATING_WINDOW, B_NOT_ZOOMABLE | B_NOT_RESIZABLE) - , fRatio(width / height) + , fOriginalWidth(width) + , fOriginalHeight(height) , fTarget(target) { BView* back_view = new BBox(Bounds(), "", B_FOLLOW_ALL); @@ -73,13 +74,13 @@ ResizerWindow::ResizerWindow(BMessenger target, float width, float height) BRect rect(left, top, width2 - kHorizontalIndent, top + 10); BString widthValue; - widthValue << (int)width2; + widthValue << width; fWidth = new BTextControl(rect, "width", kWidthLabel, widthValue.String(), NULL); fWidth->SetModificationMessage(new BMessage(kWidthModifiedMsg)); AddControl(back_view, fWidth, column2, rect); BString heightValue; - heightValue << (int)height; + heightValue << height; fHeight = new BTextControl(rect, "height", kHeightLabel, heightValue.String(), NULL); fHeight->SetModificationMessage(new BMessage(kHeightModifiedMsg)); AddControl(back_view, fHeight, column2, rect); @@ -154,15 +155,16 @@ ResizerWindow::MessageReceived(BMessage* message) case kUpdateMsg: { // update aspect ratio, width and height - float width, height; - if (message->FindFloat("width", &width) == B_OK && - message->FindFloat("height", &height) == B_OK) { - - fRatio = width / height; + int32 width, height; + if (message->FindInt32("width", &width) == B_OK && + message->FindInt32("height", &height) == B_OK) { + + fOriginalWidth = width; + fOriginalHeight = height; BString widthText, heightText; - widthText << (int)width; - heightText << (int)height; + widthText << width; + heightText << height; // here the statement order is important: // in case keep aspect ratio is enabled, // the width should determine the height @@ -186,7 +188,7 @@ ResizerWindow::MessageReceived(BMessage* message) if (fAspectRatio->Value() == B_CONTROL_ON) { int w = atoi(fWidth->Text()); - int h = (int)(w / fRatio); + int h = (int)((int64)w * (int64) fOriginalHeight / (int64) fOriginalWidth); BString height; height << h; BMessage* msg = new BMessage(*fHeight->ModificationMessage()); @@ -199,7 +201,7 @@ ResizerWindow::MessageReceived(BMessage* message) if (fAspectRatio->Value() == B_CONTROL_ON) { int h = atoi(fHeight->Text()); - int w = (int)(h * fRatio); + int w = (int)((int64)h * (int64) fOriginalWidth / (int64) fOriginalHeight); BString width; width << w; BMessage* msg = new BMessage(*fWidth->ModificationMessage()); diff --git a/src/apps/showimage/ResizerWindow.h b/src/apps/showimage/ResizerWindow.h index 9e6614220d..2f5820774f 100644 --- a/src/apps/showimage/ResizerWindow.h +++ b/src/apps/showimage/ResizerWindow.h @@ -41,7 +41,7 @@ class BCheckBox; class ResizerWindow : public BWindow { public: - ResizerWindow(BMessenger target, float width, float height ); + ResizerWindow(BMessenger target, int32 width, int32 height ); virtual void MessageReceived(BMessage* msg); virtual bool QuitRequested(); @@ -53,7 +53,7 @@ class ResizerWindow : public BWindow kActivateMsg = 'RSRa', // activates the window kUpdateMsg, - // provides the new size of the image in two float fields "width" and "height" + // provides the new size of the image in two "int32" fields "width" and "height" }; private: enum { @@ -71,7 +71,10 @@ class ResizerWindow : public BWindow BTextControl* fHeight; BCheckBox* fAspectRatio; BButton* fApply; - float fRatio; + // the original size of the image use for aspect ratio calculation + // to avoid rounding errors + int32 fOriginalWidth; + int32 fOriginalHeight; BMessenger fTarget; }; diff --git a/src/apps/showimage/ShowImageWindow.cpp b/src/apps/showimage/ShowImageWindow.cpp index c663c40da5..f5e82c0dfa 100644 --- a/src/apps/showimage/ShowImageWindow.cpp +++ b/src/apps/showimage/ShowImageWindow.cpp @@ -596,12 +596,14 @@ ShowImageWindow::MessageReceived(BMessage *message) int32 width, height; if (message->FindInt32("width", &width) >= B_OK && message->FindInt32("height", &height) >= B_OK) { - status << width << "x" << height << ", "; + status << width << "x" << height; messageProvidesSize = true; } BString str; - if (message->FindString("status", &str) == B_OK) { + if (message->FindString("status", &str) == B_OK && str.Length() > 0) { + if (status.Length() > 0) + status << ", "; status << str; } @@ -822,7 +824,7 @@ ShowImageWindow::MessageReceived(BMessage *message) if (fImageView->GetBitmap() != NULL) { BRect rect = fImageView->GetBitmap()->Bounds(); - OpenResizerWindow(rect.Width(), rect.Height()); + OpenResizerWindow(rect.IntegerWidth()+1, rect.IntegerHeight()+1); } break; case MSG_RESIZE: @@ -1139,7 +1141,7 @@ ShowImageWindow::Print(BMessage *msg) } void -ShowImageWindow::OpenResizerWindow(float width, float height) +ShowImageWindow::OpenResizerWindow(int32 width, int32 height) { if (fResizerWindowMessenger == NULL) { // open window if it is not already opened @@ -1151,7 +1153,7 @@ ShowImageWindow::OpenResizerWindow(float width, float height) } void -ShowImageWindow::UpdateResizerWindow(float width, float height) +ShowImageWindow::UpdateResizerWindow(int32 width, int32 height) { if (fResizerWindowMessenger == NULL) { // window not opened @@ -1159,8 +1161,8 @@ ShowImageWindow::UpdateResizerWindow(float width, float height) } BMessage updateMsg(ResizerWindow::kUpdateMsg); - updateMsg.AddFloat("width", width); - updateMsg.AddFloat("height", height); + updateMsg.AddInt32("width", width); + updateMsg.AddInt32("height", height); fResizerWindowMessenger->SendMessage(&updateMsg); } diff --git a/src/apps/showimage/ShowImageWindow.h b/src/apps/showimage/ShowImageWindow.h index 900990fd72..7700bef17f 100644 --- a/src/apps/showimage/ShowImageWindow.h +++ b/src/apps/showimage/ShowImageWindow.h @@ -78,8 +78,8 @@ class ShowImageWindow : public BWindow { void PrepareForPrint(); void Print(BMessage *msg); - void OpenResizerWindow(float width, float height); - void UpdateResizerWindow(float width, float height); + void OpenResizerWindow(int32 width, int32 height); + void UpdateResizerWindow(int32 width, int32 height); void CloseResizerWindow(); BFilePanel *fSavePanel;