diff --git a/headers/build/HaikuBuildCompatibility.h b/headers/build/HaikuBuildCompatibility.h index 5b6380c67a..b824b8e0c1 100644 --- a/headers/build/HaikuBuildCompatibility.h +++ b/headers/build/HaikuBuildCompatibility.h @@ -135,6 +135,7 @@ extern float roundf(float value); # define B_MINI_ICON_TYPE 'MICN' # define B_VECTOR_ICON_TYPE 'VICN' # define B_BITMAP_NO_SERVER_LINK 0 +# define B_BITMAP_SCALE_BILINEAR 0 # endif #endif // HAIKU_TARGET_PLATFORM_LIBBE_TEST diff --git a/headers/os/interface/Bitmap.h b/headers/os/interface/Bitmap.h index 6df3f5a575..d014231911 100644 --- a/headers/os/interface/Bitmap.h +++ b/headers/os/interface/Bitmap.h @@ -28,7 +28,11 @@ enum { B_BITMAP_IS_OFFSCREEN = 0x00000020, B_BITMAP_WILL_OVERLAY = 0x00000040 | B_BITMAP_IS_OFFSCREEN, B_BITMAP_RESERVE_OVERLAY_CHANNEL = 0x00000080, - B_BITMAP_NO_SERVER_LINK = 0x00000100 + // Haiku extensions: + B_BITMAP_NO_SERVER_LINK = 0x00000100, + B_BITMAP_SCALE_BILINEAR = 0x00000200 + // TODO: Make this simply "SMOOTH_SCALE" and use + // better quality methods the faster the computer? }; #define B_ANY_BYTES_PER_ROW -1 diff --git a/src/kits/interface/Bitmap.cpp b/src/kits/interface/Bitmap.cpp index 354e1e2708..a34d776298 100644 --- a/src/kits/interface/Bitmap.cpp +++ b/src/kits/interface/Bitmap.cpp @@ -997,7 +997,7 @@ BBitmap::_InitObject(BRect bounds, color_space colorSpace, uint32 flags, link.StartMessage(AS_CREATE_BITMAP); link.Attach(bounds); link.Attach(colorSpace); - link.Attach((int32)flags); + link.Attach(flags); link.Attach(bytesPerRow); link.Attach(screenID.id); diff --git a/src/servers/app/BitmapManager.cpp b/src/servers/app/BitmapManager.cpp index 08c9d396f3..954626cc02 100644 --- a/src/servers/app/BitmapManager.cpp +++ b/src/servers/app/BitmapManager.cpp @@ -89,7 +89,7 @@ BitmapManager::~BitmapManager() */ ServerBitmap* BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, - HWInterface& hwInterface, BRect bounds, color_space space, int32 flags, + HWInterface& hwInterface, BRect bounds, color_space space, uint32 flags, int32 bytesPerRow, screen_id screen, uint8* _allocationFlags) { BAutolock locker(fLock); diff --git a/src/servers/app/BitmapManager.h b/src/servers/app/BitmapManager.h index 4b94cb9e29..19c3feade8 100644 --- a/src/servers/app/BitmapManager.h +++ b/src/servers/app/BitmapManager.h @@ -26,7 +26,8 @@ class BitmapManager { ServerBitmap* CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInterface, BRect bounds, - color_space space, int32 flags, int32 bytesPerRow = -1, + color_space space, uint32 flags, + int32 bytesPerRow = -1, screen_id screen = B_MAIN_SCREEN_ID, uint8* _allocationFlags = NULL); void DeleteBitmap(ServerBitmap* bitmap); diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 1198a2805a..09ca4fc6b7 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -587,12 +587,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) BRect frame; color_space colorSpace; - int32 flags, bytesPerRow; + uint32 flags; + int32 bytesPerRow; screen_id screenID; link.Read(&frame); link.Read(&colorSpace); - link.Read(&flags); + link.Read(&flags); link.Read(&bytesPerRow); if (link.Read(&screenID) == B_OK) { // TODO: choose the right HWInterface with regards to the screenID diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index 80fe6e3c91..2fd253ff3f 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -50,9 +50,8 @@ using std::nothrow; greater than the default will result in the number of bytes specified. \param screen Screen assigned to the bitmap. */ -ServerBitmap::ServerBitmap(BRect rect, color_space space, - int32 flags, int32 bytesPerRow, - screen_id screen) +ServerBitmap::ServerBitmap(BRect rect, color_space space, uint32 flags, + int32 bytesPerRow, screen_id screen) : fAllocator(NULL), fAllocationCookie(NULL), @@ -253,11 +252,10 @@ ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow) } if (minBPR > 0 || bytesPerRow > 0) { // add the padding or use the provided bytesPerRow if sufficient - if (bytesPerRow >= minBPR) { + if (bytesPerRow >= minBPR) fBytesPerRow = bytesPerRow; - } else { + else fBytesPerRow = ((minBPR + 3) / 4) * 4; - } } } @@ -346,9 +344,8 @@ ServerBitmap::PrintToStream() // #pragma mark - -UtilityBitmap::UtilityBitmap(BRect rect, color_space space, - int32 flags, int32 bytesperline, - screen_id screen) +UtilityBitmap::UtilityBitmap(BRect rect, color_space space, uint32 flags, + int32 bytesperline, screen_id screen) : ServerBitmap(rect, space, flags, bytesperline, screen) { _AllocateBuffer(); @@ -365,9 +362,8 @@ UtilityBitmap::UtilityBitmap(const ServerBitmap* bitmap) } -UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, - uint32 width, uint32 height, - color_space format) +UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, uint32 width, + uint32 height, color_space format) : ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0) { _AllocateBuffer(); diff --git a/src/servers/app/ServerBitmap.h b/src/servers/app/ServerBitmap.h index f9ef44378e..03fd882a40 100644 --- a/src/servers/app/ServerBitmap.h +++ b/src/servers/app/ServerBitmap.h @@ -54,6 +54,8 @@ class ServerBitmap { { return fBitsPerPixel; } inline color_space ColorSpace() const { return fSpace; } + inline uint32 Flags() const + { return fFlags; } //! Returns the identifier token for the bitmap inline int32 Token() const @@ -87,11 +89,9 @@ protected: friend class BitmapManager; friend class PicturePlayer; - ServerBitmap(BRect rect, - color_space space, - int32 flags, - int32 bytesPerRow = -1, - screen_id screen = B_MAIN_SCREEN_ID); + ServerBitmap(BRect rect, color_space space, + uint32 flags, int32 bytesPerRow = -1, + screen_id screen = B_MAIN_SCREEN_ID); ServerBitmap(const ServerBitmap* bmp); virtual ~ServerBitmap(); @@ -104,7 +104,7 @@ protected: void _AllocateBuffer(); void _HandleSpace(color_space space, - int32 bytesperline = -1); + int32 bytesperline = -1); ClientMemoryAllocator* fAllocator; void* fAllocationCookie; @@ -116,7 +116,7 @@ protected: int32 fHeight; int32 fBytesPerRow; color_space fSpace; - int32 fFlags; + uint32 fFlags; int fBitsPerPixel; ServerApp* fOwner; @@ -125,17 +125,14 @@ protected: class UtilityBitmap : public ServerBitmap { public: - UtilityBitmap(BRect rect, - color_space space, - int32 flags, - int32 bytesperline = -1, - screen_id screen = B_MAIN_SCREEN_ID); + UtilityBitmap(BRect rect, color_space space, + uint32 flags, int32 bytesperline = -1, + screen_id screen = B_MAIN_SCREEN_ID); UtilityBitmap(const ServerBitmap* bmp); UtilityBitmap(const uint8* alreadyPaddedData, - uint32 width, - uint32 height, - color_space format); + uint32 width, uint32 height, + color_space format); virtual ~UtilityBitmap(); diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 231cb96e79..c1b8b11b35 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -1093,7 +1093,7 @@ Painter::DrawBitmap(const ServerBitmap* bitmap, bitmap->BytesPerRow()); _DrawBitmap(srcBuffer, bitmap->ColorSpace(), actualBitmapRect, - bitmapRect, viewRect); + bitmapRect, viewRect, bitmap->Flags()); } return touched; } @@ -1350,7 +1350,8 @@ Painter::_TransparentMagicToAlpha(sourcePixel* buffer, uint32 width, // _DrawBitmap void Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, - BRect actualBitmapRect, BRect bitmapRect, BRect viewRect) const + BRect actualBitmapRect, BRect bitmapRect, BRect viewRect, + uint32 bitmapFlags) const { if (!fValidClipping || !bitmapRect.IsValid() || !bitmapRect.Intersects(actualBitmapRect) @@ -1434,7 +1435,7 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, if ((format != B_RGBA32 && format != B_RGB32) || (format == B_RGB32 && fDrawingMode != B_OP_COPY -#if 0 +#if 1 // Enabling this would make the behavior compatible to BeOS, which // treats B_RGB32 bitmaps as B_RGB*A*32 bitmaps in B_OP_ALPHA - unlike in // all other drawing modes, where B_TRANSPARENT_MAGIC_RGBA32 is handled. @@ -1513,7 +1514,8 @@ Painter::_DrawBitmap(agg::rendering_buffer& srcBuffer, color_space format, } // for all other cases (non-optimized drawing mode or scaled drawing) - _DrawBitmapGeneric32(srcBuffer, xOffset, yOffset, xScale, yScale, viewRect); + _DrawBitmapGeneric32(srcBuffer, xOffset, yOffset, xScale, yScale, viewRect, + bitmapFlags); } #define DEBUG_DRAW_BITMAP 0 @@ -1584,9 +1586,8 @@ if (left - xOffset < 0 || left - xOffset >= (int32)srcBuffer.width() || // _DrawBitmapGeneric32 void Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer, - double xOffset, double yOffset, - double xScale, double yScale, - BRect viewRect) const + double xOffset, double yOffset, double xScale, double yScale, + BRect viewRect, uint32 bitmapFlags) const { TRACE("Painter::_DrawBitmapGeneric32()\n"); TRACE(" offset: %.1f, %.1f\n", xOffset, yOffset); @@ -1622,12 +1623,6 @@ Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer, typedef agg::image_accessor_clip source_type; source_type source(pixf_img, agg::rgba8(0, 0, 0, 0)); - // image filter (nearest neighbor) - typedef agg::span_image_filter_rgba_nn span_gen_type; - span_gen_type spanGenerator(source, interpolator); - - // clip to the current clipping region's frame viewRect = viewRect & fClippingRegion->Frame(); // convert to pixel coords (versus pixel indices) @@ -1646,12 +1641,25 @@ Painter::_DrawBitmapGeneric32(agg::rendering_buffer& srcBuffer, fRasterizer.reset(); fRasterizer.add_path(transformedPath); - // render the path with the bitmap as scanline fill - agg::render_scanlines_aa(fRasterizer, - fUnpackedScanline, - fBaseRenderer, - spanAllocator, - spanGenerator); + if ((bitmapFlags & B_BITMAP_SCALE_BILINEAR) != 0) { + // image filter (bilinear) + typedef agg::span_image_filter_rgba_bilinear< + source_type, interpolator_type> span_gen_type; + span_gen_type spanGenerator(source, interpolator); + + // render the path with the bitmap as scanline fill + agg::render_scanlines_aa(fRasterizer, fUnpackedScanline, fBaseRenderer, + spanAllocator, spanGenerator); + } else { + // image filter (nearest neighbor) + typedef agg::span_image_filter_rgba_nn< + source_type, interpolator_type> span_gen_type; + span_gen_type spanGenerator(source, interpolator); + + // render the path with the bitmap as scanline fill + agg::render_scanlines_aa(fRasterizer, fUnpackedScanline, fBaseRenderer, + spanAllocator, spanGenerator); + } } // _InvertRect32 diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index 4e520f7e1a..0acea098d2 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -229,7 +229,8 @@ class Painter { color_space format, BRect actualBitmapRect, BRect bitmapRect, - BRect viewRect) const; + BRect viewRect, + uint32 bitmapFlags) const; template void _DrawBitmapNoScale32( F copyRowFunction, @@ -241,7 +242,8 @@ class Painter { agg::rendering_buffer& srcBuffer, double xOffset, double yOffset, double xScale, double yScale, - BRect viewRect) const; + BRect viewRect, + uint32 bitmapFlags) const; void _InvertRect32( BRect r) const; void _BlendRect32( const BRect& r,