diff --git a/artpaint/paintwindow/Image.cpp b/artpaint/paintwindow/Image.cpp index 0207da08..b68fbe45 100644 --- a/artpaint/paintwindow/Image.cpp +++ b/artpaint/paintwindow/Image.cpp @@ -1490,28 +1490,11 @@ Image::DoRenderPreview(BRect area, int32 resolution) int32 right = (int32)area.right; int32 bottom = (int32)area.bottom; - int32 gridSize; - uint32 color1; - uint32 color2; - - gridSize = 20; - rgb_color rgb1, rgb2; - rgb1.red = rgb1.green = rgb1.blue = 0xBB; - rgb2.red = rgb2.green = rgb2.blue = 0x99; - rgb1.alpha = rgb2.alpha = 0xFF; - color1 = RGBColorToBGRA(rgb1); - color2 = RGBColorToBGRA(rgb2); + union color_conversion white_bg; + white_bg.word = 0xFFFFFFFF; + white_bg.bytes[3] = 0x00; - if (SettingsServer* server = SettingsServer::Instance()) { - BMessage settings; - server->GetApplicationSettings(&settings); - - gridSize = settings.GetInt32(skBgGridSize, gridSize); - color1 = settings.GetUInt32(skBgColor1, color1); - color2 = settings.GetUInt32(skBgColor2, color2); - } - - BitmapUtilities::CheckerBitmap(rendered_image, color1, color2, gridSize, &area); + BitmapUtilities::ClearBitmap(rendered_image, white_bg.word, &area); for (int32 y = top; y <= bottom; y += resolution) { for (int32 x = left; x <= right; x += resolution) { diff --git a/artpaint/paintwindow/Image.h b/artpaint/paintwindow/Image.h index d904ebb3..1bfab365 100644 --- a/artpaint/paintwindow/Image.h +++ b/artpaint/paintwindow/Image.h @@ -92,8 +92,8 @@ class Image { Image(ImageView*, float, float, UndoQueue*); ~Image(); - void Render(bool bg = true); - void Render(BRect, bool bg = true); + void Render(bool bg = false); + void Render(BRect, bool bg = false); void RenderPreview(BRect, int32); void RenderPreview(BRegion&, int32); void MultiplyRenderedImagePixels(int32); diff --git a/artpaint/paintwindow/ImageView.cpp b/artpaint/paintwindow/ImageView.cpp index 0d5b5cb4..af7fcb89 100644 --- a/artpaint/paintwindow/ImageView.cpp +++ b/artpaint/paintwindow/ImageView.cpp @@ -56,6 +56,7 @@ #include +#include #undef B_TRANSLATION_CONTEXT @@ -136,6 +137,8 @@ ImageView::ImageView(BRect frame, float width, float height) show_selection = TRUE; AddFilter(new BMessageFilter(B_KEY_DOWN, KeyFilterFunction)); + + background = NULL; } @@ -167,6 +170,8 @@ ImageView::~ImageView() // Delete the semaphores delete_sem(mouse_mutex); delete_sem(action_semaphore); + + delete background; } @@ -191,15 +196,53 @@ ImageView::AttachedToWindow() MakeFocus(); SetEventMask(B_KEYBOARD_EVENTS); + + MakeBackground(); +} + + +void +ImageView::MakeBackground() +{ + int32 gridSize; + uint32 color1; + uint32 color2; + + gridSize = 20; + rgb_color rgb1, rgb2; + rgb1.red = rgb1.green = rgb1.blue = 0xBB; + rgb2.red = rgb2.green = rgb2.blue = 0x99; + rgb1.alpha = rgb2.alpha = 0xFF; + color1 = RGBColorToBGRA(rgb1); + color2 = RGBColorToBGRA(rgb2); + + if (SettingsServer* server = SettingsServer::Instance()) { + BMessage settings; + server->GetApplicationSettings(&settings); + + gridSize = settings.GetInt32(skBgGridSize, gridSize); + color1 = settings.GetUInt32(skBgColor1, color1); + color2 = settings.GetUInt32(skBgColor2, color2); + } + + if (background != NULL) + delete background; + + background = new BBitmap(BRect(0, 0, the_image->Width(), the_image->Height()), B_RGBA32); + BitmapUtilities::CheckerBitmap(background, color1, color2, gridSize); } void ImageView::Draw(BRect updateRect) { - // copy image from bitmap to the part requiring updating + Window()->BeginViewTransaction(); SetDrawingMode(B_OP_COPY); + // draw checker background + DrawBitmapAsync(background, convertViewRectToBitmap(Bounds()), Bounds()); + + // copy image from bitmap to the part requiring updating BRegion a_region; GetClippingRegion(&a_region); for (int32 i = 0; i < a_region.CountRects(); i++) @@ -209,11 +252,24 @@ ImageView::Draw(BRect updateRect) if (show_selection == TRUE) selection->Draw(); - // Make the manipulator draw it's UI here. - DrawManipulatorGUI(FALSE); + if (fManipulator == NULL) { + int32 mode = B_CONTROL_ON; + if (SettingsServer* server = SettingsServer::Instance()) { + BMessage settings; + server->GetApplicationSettings(&settings); + settings.FindInt32(skDrawBrushSizeMode, &mode); + } + + // draw current brush shape if mode is set in preferences + if (mode == B_CONTROL_ON) + DrawBrush(previous_point); + } else + // Make the manipulator draw it's UI here. + DrawManipulatorGUI(FALSE); // finally Flush() after drawing asynchronously Flush(); + Window()->EndViewTransaction(); } @@ -223,6 +279,10 @@ ImageView::BlitImage(BRect bitmap_rect) BRect image_rect; float mag_scale = getMagScale(); + drawing_mode old_mode = DrawingMode(); + SetDrawingMode(B_OP_ALPHA); + SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); + BBitmap* source_bitmap; if ((current_display_mode == FULL_RGB_DISPLAY_MODE) || (the_image->IsDitheredUpToDate() == FALSE)) @@ -230,6 +290,8 @@ ImageView::BlitImage(BRect bitmap_rect) else source_bitmap = the_image->ReturnDitheredImage(); + bitmap_rect = bitmap_rect & source_bitmap->Bounds(); + if (mag_scale == 1.0) { image_rect = bitmap_rect; DrawBitmapAsync(source_bitmap, image_rect, bitmap_rect); @@ -237,6 +299,8 @@ ImageView::BlitImage(BRect bitmap_rect) image_rect = convertBitmapRectToView(bitmap_rect); DrawBitmapAsync(source_bitmap, bitmap_rect, image_rect); } + + SetDrawingMode(old_mode); } @@ -245,7 +309,7 @@ ImageView::UpdateImage(BRect bitmap_rect) { bitmap_rect = bitmap_rect & the_image->ReturnRenderedImage()->Bounds(); the_image->Render(bitmap_rect); - BlitImage(bitmap_rect); + Invalidate(convertBitmapRectToView(bitmap_rect)); } @@ -261,13 +325,10 @@ ImageView::DrawManipulatorGUI(bool blit_image) BView* parent = this->Parent(); BRect imgFrame = ConvertToParent(Bounds()); - parent->Draw(parent->Bounds()); - parent->Flush(); parent->PushState(); parent->SetOrigin(imgFrame.LeftTop()); region_drawn_by_manipulator = gui_manipulator->Draw(parent, getMagScale()); parent->PopState(); - region_drawn_by_manipulator = gui_manipulator->Draw(this, getMagScale()); } else region_drawn_by_manipulator = BRegion(); @@ -368,7 +429,6 @@ ImageView::MessageReceived(BMessage* message) uint32 buttons; BPoint norm_point; - GetMouse(&point, &buttons); getCoords(&norm_point, &buttons, &point); float magScale = getMagScale(); @@ -418,7 +478,6 @@ ImageView::MessageReceived(BMessage* message) if (magScale <= 16.0) { setMagScale(magScale); - float delta_x = norm_point.x * scaleChange; float delta_y = norm_point.y * scaleChange; @@ -1017,6 +1076,7 @@ ImageView::MessageReceived(BMessage* message) the_image->Render(); manipulated_layers = HS_MANIPULATE_NO_LAYER; Parent()->Draw(Parent()->Bounds()); + MakeBackground(); Invalidate(); start_thread(MANIPULATOR_FINISHER_THREAD); } @@ -1085,6 +1145,9 @@ ImageView::MouseDown(BPoint view_point) be_app->SetCursor(fGrabbingCursor); ScrollBy(delta_x, delta_y); + BRegion a_region; + GetClippingRegion(&a_region); + Invalidate(&a_region); snooze(25 * 1000); } @@ -1115,20 +1178,6 @@ ImageView::MouseDown(BPoint view_point) void ImageView::MouseUp(BPoint where) { - if (fManipulator == NULL) { - where.x = floor(where.x / getMagScale()); - where.y = floor(where.y / getMagScale()); - - int32 mode = B_CONTROL_ON; - if (SettingsServer* server = SettingsServer::Instance()) { - BMessage settings; - server->GetApplicationSettings(&settings); - settings.FindInt32(skDrawBrushSizeMode, &mode); - } - - if (mode == B_CONTROL_ON) - DrawBrush(where); - } } @@ -1175,32 +1224,40 @@ ImageView::MouseMoved(BPoint where, uint32 transit, const BMessage* message) // Here we set the window to display coordinates. ((PaintWindow*)Window())->DisplayCoordinates(where, reference_point, use_reference_point); - if (fManipulator == NULL) { - int32 mode = B_CONTROL_ON; - if (SettingsServer* server = SettingsServer::Instance()) { - BMessage settings; - server->GetApplicationSettings(&settings); - settings.FindInt32(skDrawBrushSizeMode, &mode); - } + // get current brush + int32 tool_type = ToolManager::Instance().ReturnActiveToolType(); + DrawingTool* tool = ToolManager::Instance().ReturnTool(tool_type); + float width = tool->GetCurrentValue(SIZE_OPTION); + float height = width; + + drawing_mode old_mode = DrawingMode(); + + Brush* brush; + if (tool->GetCurrentValue(USE_BRUSH_OPTION)) { + brush = ToolManager::Instance().GetCurrentBrush(); + width = brush->Width(); + height = brush->Height(); + } else + brush = NULL; - if (mode == B_CONTROL_ON) { - uint32 buttons = 0; - BMessage* move_message = Window()->CurrentMessage(); + // invalidate area where brush was drawn + float half_width = ceil(width / 2.); + float half_height = ceil(height / 2.); - if (move_message != NULL) - buttons = move_message->FindInt32("buttons"); + BRect clear_rect; + clear_rect.left = min_c(previous_point.x, where.x) - half_width; + clear_rect.top = min_c(previous_point.y, where.y) - half_height; + clear_rect.right = max_c(previous_point.x, where.x) + half_width; + clear_rect.bottom = max_c(previous_point.y, where.y) + half_height; - if (buttons == 0) - DrawBrush(where); - } - } + Invalidate(convertBitmapRectToView(clear_rect)); } else { where.x = the_image->Width(); where.y = the_image->Height(); ((PaintWindow*)Window())->DisplayCoordinates(where, BPoint(0, 0), false); - Draw(Bounds()); + Invalidate(Bounds()); } previous_point = where; @@ -1208,7 +1265,7 @@ ImageView::MouseMoved(BPoint where, uint32 transit, const BMessage* message) void -ImageView::DrawBrush(BPoint where) +ImageView:: DrawBrush(BPoint where) { int32 tool_type = ToolManager::Instance().ReturnActiveToolType(); @@ -1216,7 +1273,8 @@ ImageView::DrawBrush(BPoint where) || tool_type == AIR_BRUSH_TOOL || tool_type == ERASER_TOOL || tool_type == BLUR_TOOL - || tool_type == TRANSPARENCY_TOOL) { + || tool_type == TRANSPARENCY_TOOL + || tool_type == COLOR_SELECTOR_TOOL) { DrawingTool* tool = ToolManager::Instance().ReturnTool(tool_type); float width = tool->GetCurrentValue(SIZE_OPTION); float height = width; @@ -1231,18 +1289,8 @@ ImageView::DrawBrush(BPoint where) } else brush = NULL; - float half_width = width / 2; - float half_height = height / 2; - - BRect clear_rect; - clear_rect.left = min_c(previous_point.x, where.x) - width - 5; - clear_rect.top = min_c(previous_point.y, where.y) - height - 5; - clear_rect.right = max_c(previous_point.x, where.x) + width + 5; - clear_rect.bottom = max_c(previous_point.y, where.y) + height + 5; - - clear_rect = convertBitmapRectToView(clear_rect); - - Draw(clear_rect); + float half_width = (width / 2.); + float half_height = (height / 2.); SetDrawingMode(B_OP_INVERT); BRect brush_rect; @@ -1253,8 +1301,16 @@ ImageView::DrawBrush(BPoint where) brush_rect.right = where.x + half_width; brush_rect.bottom = where.y + half_height; - brush_rect = convertBitmapRectToView(brush_rect); - StrokeEllipse(brush_rect); + if (tool_type == COLOR_SELECTOR_TOOL) { + if ((int32)width % 2 == 0) { + brush_rect.right -= 1; + brush_rect.bottom -= 1; + } else + brush_rect.InsetBy(0.5, 0.5); + + StrokeRect(convertBitmapRectToView(brush_rect)); + } else + StrokeEllipse(convertBitmapRectToView(brush_rect)); } else { int num_shapes = brush->GetNumShapes(); BPolygon** shapes = new BPolygon*[num_shapes]; @@ -1810,8 +1866,10 @@ ImageView::ManipulatorMouseTrackerThread() } else the_image->MultiplyRenderedImagePixels(preview_quality); + Parent()->Invalidate(); + for (int32 i = 0; i < updated_region->CountRects(); i++) - Draw(convertBitmapRectToView(updated_region->RectAt(i))); + Invalidate(convertBitmapRectToView(updated_region->RectAt(i))); } else if (preview_quality == DRAW_ONLY_GUI) { DrawManipulatorGUI(TRUE); if (show_selection == TRUE) @@ -1843,8 +1901,10 @@ ImageView::ManipulatorMouseTrackerThread() the_image->MultiplyRenderedImagePixels(preview_quality); if (LockLooper() == TRUE) { + Parent()->Invalidate(); + for (int32 i = 0; i < updated_region->CountRects(); i++) - Draw(convertBitmapRectToView(updated_region->RectAt(i))); + Invalidate(convertBitmapRectToView(updated_region->RectAt(i))); UnlockLooper(); } } else if (preview_quality == DRAW_ONLY_GUI) { @@ -1893,7 +1953,7 @@ ImageView::GUIManipulatorUpdaterThread() the_image->MultiplyRenderedImagePixels(preview_quality); for (int32 i = 0; i < updated_region->CountRects(); i++) - Draw(convertBitmapRectToView(updated_region->RectAt(i))); + Invalidate(convertBitmapRectToView(updated_region->RectAt(i))); } else if (preview_quality == DRAW_ONLY_GUI) { DrawManipulatorGUI(TRUE); if (show_selection == TRUE) @@ -1929,7 +1989,7 @@ ImageView::GUIManipulatorUpdaterThread() if (LockLooper() == TRUE) { for (int32 i = 0; i < updated_region->CountRects(); i++) - Draw(convertBitmapRectToView(updated_region->RectAt(i))); + Invalidate(convertBitmapRectToView(updated_region->RectAt(i))); UnlockLooper(); } } else if (preview_quality == DRAW_ONLY_GUI) { @@ -2124,6 +2184,7 @@ ImageView::ManipulatorFinisherThread() the_image->SetImageSize(); the_image->Render(); + MakeBackground(); // Change the selection for the undo-queue if necessary. if ((new_event != NULL) @@ -2237,6 +2298,7 @@ ImageView::Undo() } the_image->Render(); + MakeBackground(); Invalidate(); } @@ -2323,6 +2385,7 @@ ImageView::Redo() } the_image->Render(); + MakeBackground(); Invalidate(); } diff --git a/artpaint/paintwindow/ImageView.h b/artpaint/paintwindow/ImageView.h index aa8ed316..e9ea34c9 100644 --- a/artpaint/paintwindow/ImageView.h +++ b/artpaint/paintwindow/ImageView.h @@ -72,6 +72,7 @@ class ImageView : public BView { private: friend filter_result KeyFilterFunction(BMessage*, BHandler**, BMessageFilter*); Image* the_image; + BBitmap* background; int32 mag_scale_array_length; int32 mag_scale_array_index; @@ -249,6 +250,7 @@ class ImageView : public BView { const char* ReturnImageName() { return image_name; } bool ShowSelection() { return show_selection; } + void MakeBackground(); }; filter_result KeyFilterFunction(BMessage*, BHandler**, BMessageFilter*); diff --git a/artpaint/paintwindow/PaintWindow.cpp b/artpaint/paintwindow/PaintWindow.cpp index dfb38279..5993521d 100644 --- a/artpaint/paintwindow/PaintWindow.cpp +++ b/artpaint/paintwindow/PaintWindow.cpp @@ -437,6 +437,7 @@ PaintWindow::Redraw() ImageView* imgView = paintWin->ReturnImageView(); if (imgView != NULL) { if (imgView->LockLooper() == true) { + imgView->MakeBackground(); imgView->ReturnImage()->Render(); imgView->Invalidate(); imgView->UnlockLooper(); diff --git a/artpaint/tools/ColorSelectorTool.cpp b/artpaint/tools/ColorSelectorTool.cpp index 8ce30610..5ec117a3 100644 --- a/artpaint/tools/ColorSelectorTool.cpp +++ b/artpaint/tools/ColorSelectorTool.cpp @@ -325,21 +325,6 @@ ColorSelectorTool::UseTool(ImageView* view, uint32 buttons, BPoint point, BPoint rc.OffsetBySelf(-half_size, -half_size); rc = rc & bounds; - view_rc = view->convertBitmapRectToView(rc); - scale = view->getMagScale(); - view_rc.right -= scale; - view_rc.bottom -= scale; - - if (view->LockLooper() == true) { - if (old_rc != view_rc) { - old_rc.InsetBySelf(-2, -2); - view->Draw(old_rc); - view->StrokeRect(view_rc, B_SOLID_HIGH); - view->StrokeRect(view_rc.InsetByCopy(-1, -1), B_SOLID_LOW); - old_rc = view_rc; - } - view->UnlockLooper(); - } int32 x_dist, y_sqr; int32 width = rc.IntegerWidth(); @@ -399,11 +384,6 @@ ColorSelectorTool::UseTool(ImageView* view, uint32 buttons, BPoint point, BPoint snooze(20 * 1000); } - if (view->LockLooper() == true) { - view->Draw(view_rc.InsetByCopy(-1, -1)); - view->UnlockLooper(); - } - // Close the color picker window if (cs_window != NULL) { cs_window->Lock(); diff --git a/artpaint/tools/EraserTool.cpp b/artpaint/tools/EraserTool.cpp index 2074a3c8..44e35a04 100644 --- a/artpaint/tools/EraserTool.cpp +++ b/artpaint/tools/EraserTool.cpp @@ -216,6 +216,7 @@ EraserTool::UseTool(ImageView* view, uint32 buttons, BPoint point, BPoint) updated_rect.bottom = max_c(point.y + brush_height_per_2 + 1, prev_point.y + brush_height_per_2 + 1); + updated_rect = updated_rect & buffer->Bounds(); imageUpdater->AddRect(updated_rect); SetLastUpdatedRect(LastUpdatedRect() | updated_rect); diff --git a/artpaint/tools/FreeLineTool.cpp b/artpaint/tools/FreeLineTool.cpp index ef6e5e0e..29d8908d 100644 --- a/artpaint/tools/FreeLineTool.cpp +++ b/artpaint/tools/FreeLineTool.cpp @@ -189,6 +189,7 @@ FreeLineTool::UseTool(ImageView* view, uint32 buttons, BPoint point, BPoint) updated_rect.bottom = max_c(point.y + brush_height_per_2 + 1, prev_point.y + brush_height_per_2 + 1); + updated_rect = updated_rect & buffer->Bounds(); imageUpdater->AddRect(updated_rect); SetLastUpdatedRect(LastUpdatedRect() | updated_rect); diff --git a/artpaint/tools/HairyBrushTool.cpp b/artpaint/tools/HairyBrushTool.cpp index 78f30b4e..6763f6a8 100644 --- a/artpaint/tools/HairyBrushTool.cpp +++ b/artpaint/tools/HairyBrushTool.cpp @@ -222,6 +222,8 @@ HairyBrushTool::UseTool(ImageView* view, uint32 buttons, BPoint point, BPoint) updated_rect.right = ceil(updated_rect.right); updated_rect.bottom = ceil(updated_rect.bottom); updated_rect.InsetBy(-1, -1); + updated_rect = updated_rect & buffer->Bounds(); + imageUpdater->AddRect(updated_rect); SetLastUpdatedRect(updated_rect); } else @@ -340,6 +342,7 @@ HairyBrushTool::UseTool(ImageView* view, uint32 buttons, BPoint point, BPoint) updated_rect.bottom = ceil(updated_rect.bottom); updated_rect.InsetBy(-1, -1); + updated_rect = updated_rect & buffer->Bounds(); SetLastUpdatedRect(LastUpdatedRect() | updated_rect); imageUpdater->AddRect(updated_rect); diff --git a/artpaint/viewmanipulators/TranslationManipulator.cpp b/artpaint/viewmanipulators/TranslationManipulator.cpp index 4678e238..741ad5cc 100644 --- a/artpaint/viewmanipulators/TranslationManipulator.cpp +++ b/artpaint/viewmanipulators/TranslationManipulator.cpp @@ -496,7 +496,8 @@ TranslationManipulator::PreviewBitmap(bool full_quality, BRegion* updated_region if (selection->ContainsPoint(new_x , new_y) && new_x >= 0 && new_y >= 0) *(target_bits + x + y * target_bpr) - = *(source_bits + new_x + new_y * source_bpr); + = src_over_fixed(*(target_bits + x + y * target_bpr), + *(source_bits + new_x + new_y * source_bpr)); } } }