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
This commit is contained in:
Michael Pfeiffer
2006-12-17 18:18:29 +00:00
parent c72e5d2fdf
commit 0acb8cc41c
4 changed files with 32 additions and 25 deletions
+15 -13
View File
@@ -50,9 +50,10 @@ static const float kLineDistance = 5;
static const float kHorizontalIndent = 10; static const float kHorizontalIndent = 10;
static const float kVerticalIndent = 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) : 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) , fTarget(target)
{ {
BView* back_view = new BBox(Bounds(), "", B_FOLLOW_ALL); 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); BRect rect(left, top, width2 - kHorizontalIndent, top + 10);
BString widthValue; BString widthValue;
widthValue << (int)width2; widthValue << width;
fWidth = new BTextControl(rect, "width", kWidthLabel, widthValue.String(), NULL); fWidth = new BTextControl(rect, "width", kWidthLabel, widthValue.String(), NULL);
fWidth->SetModificationMessage(new BMessage(kWidthModifiedMsg)); fWidth->SetModificationMessage(new BMessage(kWidthModifiedMsg));
AddControl(back_view, fWidth, column2, rect); AddControl(back_view, fWidth, column2, rect);
BString heightValue; BString heightValue;
heightValue << (int)height; heightValue << height;
fHeight = new BTextControl(rect, "height", kHeightLabel, heightValue.String(), NULL); fHeight = new BTextControl(rect, "height", kHeightLabel, heightValue.String(), NULL);
fHeight->SetModificationMessage(new BMessage(kHeightModifiedMsg)); fHeight->SetModificationMessage(new BMessage(kHeightModifiedMsg));
AddControl(back_view, fHeight, column2, rect); AddControl(back_view, fHeight, column2, rect);
@@ -154,15 +155,16 @@ ResizerWindow::MessageReceived(BMessage* message)
case kUpdateMsg: case kUpdateMsg:
{ {
// update aspect ratio, width and height // update aspect ratio, width and height
float width, height; int32 width, height;
if (message->FindFloat("width", &width) == B_OK && if (message->FindInt32("width", &width) == B_OK &&
message->FindFloat("height", &height) == B_OK) { message->FindInt32("height", &height) == B_OK) {
fRatio = width / height; fOriginalWidth = width;
fOriginalHeight = height;
BString widthText, heightText; BString widthText, heightText;
widthText << (int)width; widthText << width;
heightText << (int)height; heightText << height;
// here the statement order is important: // here the statement order is important:
// in case keep aspect ratio is enabled, // in case keep aspect ratio is enabled,
// the width should determine the height // the width should determine the height
@@ -186,7 +188,7 @@ ResizerWindow::MessageReceived(BMessage* message)
if (fAspectRatio->Value() == B_CONTROL_ON) if (fAspectRatio->Value() == B_CONTROL_ON)
{ {
int w = atoi(fWidth->Text()); int w = atoi(fWidth->Text());
int h = (int)(w / fRatio); int h = (int)((int64)w * (int64) fOriginalHeight / (int64) fOriginalWidth);
BString height; BString height;
height << h; height << h;
BMessage* msg = new BMessage(*fHeight->ModificationMessage()); BMessage* msg = new BMessage(*fHeight->ModificationMessage());
@@ -199,7 +201,7 @@ ResizerWindow::MessageReceived(BMessage* message)
if (fAspectRatio->Value() == B_CONTROL_ON) if (fAspectRatio->Value() == B_CONTROL_ON)
{ {
int h = atoi(fHeight->Text()); int h = atoi(fHeight->Text());
int w = (int)(h * fRatio); int w = (int)((int64)h * (int64) fOriginalWidth / (int64) fOriginalHeight);
BString width; BString width;
width << w; width << w;
BMessage* msg = new BMessage(*fWidth->ModificationMessage()); BMessage* msg = new BMessage(*fWidth->ModificationMessage());
+6 -3
View File
@@ -41,7 +41,7 @@ class BCheckBox;
class ResizerWindow : public BWindow class ResizerWindow : public BWindow
{ {
public: public:
ResizerWindow(BMessenger target, float width, float height ); ResizerWindow(BMessenger target, int32 width, int32 height );
virtual void MessageReceived(BMessage* msg); virtual void MessageReceived(BMessage* msg);
virtual bool QuitRequested(); virtual bool QuitRequested();
@@ -53,7 +53,7 @@ class ResizerWindow : public BWindow
kActivateMsg = 'RSRa', kActivateMsg = 'RSRa',
// activates the window // activates the window
kUpdateMsg, 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: private:
enum { enum {
@@ -71,7 +71,10 @@ class ResizerWindow : public BWindow
BTextControl* fHeight; BTextControl* fHeight;
BCheckBox* fAspectRatio; BCheckBox* fAspectRatio;
BButton* fApply; 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; BMessenger fTarget;
}; };
+9 -7
View File
@@ -596,12 +596,14 @@ ShowImageWindow::MessageReceived(BMessage *message)
int32 width, height; int32 width, height;
if (message->FindInt32("width", &width) >= B_OK if (message->FindInt32("width", &width) >= B_OK
&& message->FindInt32("height", &height) >= B_OK) { && message->FindInt32("height", &height) >= B_OK) {
status << width << "x" << height << ", "; status << width << "x" << height;
messageProvidesSize = true; messageProvidesSize = true;
} }
BString str; 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; status << str;
} }
@@ -822,7 +824,7 @@ ShowImageWindow::MessageReceived(BMessage *message)
if (fImageView->GetBitmap() != NULL) if (fImageView->GetBitmap() != NULL)
{ {
BRect rect = fImageView->GetBitmap()->Bounds(); BRect rect = fImageView->GetBitmap()->Bounds();
OpenResizerWindow(rect.Width(), rect.Height()); OpenResizerWindow(rect.IntegerWidth()+1, rect.IntegerHeight()+1);
} }
break; break;
case MSG_RESIZE: case MSG_RESIZE:
@@ -1139,7 +1141,7 @@ ShowImageWindow::Print(BMessage *msg)
} }
void void
ShowImageWindow::OpenResizerWindow(float width, float height) ShowImageWindow::OpenResizerWindow(int32 width, int32 height)
{ {
if (fResizerWindowMessenger == NULL) { if (fResizerWindowMessenger == NULL) {
// open window if it is not already opened // open window if it is not already opened
@@ -1151,7 +1153,7 @@ ShowImageWindow::OpenResizerWindow(float width, float height)
} }
void void
ShowImageWindow::UpdateResizerWindow(float width, float height) ShowImageWindow::UpdateResizerWindow(int32 width, int32 height)
{ {
if (fResizerWindowMessenger == NULL) { if (fResizerWindowMessenger == NULL) {
// window not opened // window not opened
@@ -1159,8 +1161,8 @@ ShowImageWindow::UpdateResizerWindow(float width, float height)
} }
BMessage updateMsg(ResizerWindow::kUpdateMsg); BMessage updateMsg(ResizerWindow::kUpdateMsg);
updateMsg.AddFloat("width", width); updateMsg.AddInt32("width", width);
updateMsg.AddFloat("height", height); updateMsg.AddInt32("height", height);
fResizerWindowMessenger->SendMessage(&updateMsg); fResizerWindowMessenger->SendMessage(&updateMsg);
} }
+2 -2
View File
@@ -78,8 +78,8 @@ class ShowImageWindow : public BWindow {
void PrepareForPrint(); void PrepareForPrint();
void Print(BMessage *msg); void Print(BMessage *msg);
void OpenResizerWindow(float width, float height); void OpenResizerWindow(int32 width, int32 height);
void UpdateResizerWindow(float width, float height); void UpdateResizerWindow(int32 width, int32 height);
void CloseResizerWindow(); void CloseResizerWindow();
BFilePanel *fSavePanel; BFilePanel *fSavePanel;