From b7af05771df69e87be7560cd3aebf58d7e9818ba Mon Sep 17 00:00:00 2001 From: DarkWyrm Date: Sat, 7 Feb 2004 13:50:36 +0000 Subject: [PATCH] Added UtilityBitmap class for general-purpose bitmaps in the server Implemented blit methods in ViewDriver - doesn't quite work yet :( Implmemented cursor methods in DisplayDriver - doesn't quite work yet, but wil be fixed later Color tweak to DefaultDecorator git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6520 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/server/DisplayDriver.cpp | 38 ++++++- src/servers/app/server/ServerBitmap.cpp | 22 +++- src/servers/app/server/ViewDriver.cpp | 130 +++++++++++++++++++++-- src/servers/app/server/ViewDriver.h | 12 ++- 4 files changed, 187 insertions(+), 15 deletions(-) diff --git a/src/servers/app/server/DisplayDriver.cpp b/src/servers/app/server/DisplayDriver.cpp index c4207b213b..6fb94867ce 100644 --- a/src/servers/app/server/DisplayDriver.cpp +++ b/src/servers/app/server/DisplayDriver.cpp @@ -1634,7 +1634,37 @@ bool DisplayDriver::IsCursorHidden(void) */ void DisplayDriver::MoveCursorTo(const float &x, const float &y) { + Lock(); + if(cursorframe.left==x && cursorframe.top==y) + { + Unlock(); + return; + } + + if(_is_cursor_obscured) + _is_cursor_obscured=false; + + oldcursorframe=cursorframe; + cursorframe.OffsetTo(x,y); + + if(_is_cursor_hidden) + { + Unlock(); + return; + } + +// if(!_cursorsave) +// _cursorsave=new ServerBitmap(_cursor); + + CopyBitmap(_cursorsave,_cursor->Bounds(),saveframe,&_drawdata); + + CopyToBitmap(_cursorsave,cursorframe); + saveframe=cursorframe; + + CopyBitmap(_cursor,_cursor->Bounds(),cursorframe,&_drawdata); + + Unlock(); } /*! @@ -1729,7 +1759,7 @@ void DisplayDriver::SetCursor(ServerCursor *cursor) _cursor=new ServerCursor(cursor); if(visible) - _cursorsave=new ServerBitmap((ServerBitmap*)cursor); + _cursorsave=new UtilityBitmap((ServerBitmap*)cursor); // TODO: make this take the hotspot into account -- too tired to bother right now... saveframe=_cursor->Bounds().OffsetToCopy(cursorframe.LeftTop()); @@ -2311,6 +2341,12 @@ void DisplayDriver::SetMode(const display_mode &mode) */ void DisplayDriver::GetMode(display_mode *mode) { + if(!mode) + return; + + Lock(); + *mode=_displaymode; + Unlock(); } /*! diff --git a/src/servers/app/server/ServerBitmap.cpp b/src/servers/app/server/ServerBitmap.cpp index 49bf906f39..6803168ab0 100644 --- a/src/servers/app/server/ServerBitmap.cpp +++ b/src/servers/app/server/ServerBitmap.cpp @@ -89,7 +89,7 @@ ServerBitmap::~ServerBitmap(void) \brief Gets the number of bytes occupied by the bitmap, including padding bytes. \return The number of bytes occupied by the bitmap, including padding. */ -uint32 ServerBitmap::BitsLength(void) +uint32 ServerBitmap::BitsLength(void) const { return (uint32)(_bytesperrow*_height); } @@ -250,3 +250,23 @@ void ServerBitmap::_HandleSpace(color_space space, int32 bytesperline) break; } } + +UtilityBitmap::UtilityBitmap(BRect rect,color_space space, int32 flags, + int32 bytesperline, screen_id screen) +: ServerBitmap(rect,space,flags,bytesperline,screen) +{ + _AllocateBuffer(); +} + +UtilityBitmap::UtilityBitmap(const ServerBitmap *bmp) +: ServerBitmap(bmp) +{ + _AllocateBuffer(); + if(bmp->Bits()) + memcpy(Bits(),bmp->Bits(),bmp->BitsLength()); +} + +UtilityBitmap::~UtilityBitmap(void) +{ + _FreeBuffer(); +} diff --git a/src/servers/app/server/ViewDriver.cpp b/src/servers/app/server/ViewDriver.cpp index 9f46b299ca..8d197637a0 100644 --- a/src/servers/app/server/ViewDriver.cpp +++ b/src/servers/app/server/ViewDriver.cpp @@ -974,7 +974,7 @@ void ViewDriver::StrokeSolidRect(const BRect &rect, RGBColor &color) screenwin->Unlock(); } -void ViewDriver::SetLayerData(LayerData *d, bool set_font_data) +void ViewDriver::SetDrawData(const DrawData *d, bool set_font_data) { if(!is_initialized) return; @@ -982,6 +982,13 @@ void ViewDriver::SetLayerData(LayerData *d, bool set_font_data) if(!d) return; + bool unlock=false; + if(!framebuffer->IsLocked()) + { + framebuffer->Lock(); + unlock=true; + } + drawview->SetPenSize(d->pensize); drawview->SetDrawingMode(d->draw_mode); drawview->SetHighColor(d->highcolor.GetColor32()); @@ -991,7 +998,7 @@ void ViewDriver::SetLayerData(LayerData *d, bool set_font_data) if(set_font_data) { BFont font; - ServerFont *sf=&(d->font); + const ServerFont *sf=&(d->font); if(!sf) return; @@ -1016,10 +1023,12 @@ void ViewDriver::SetLayerData(LayerData *d, bool set_font_data) font.SetSpacing(sf->Spacing()); drawview->SetFont(&font); } + if(unlock) + framebuffer->Unlock(); } /* -float ViewDriver::StringWidth(const char *string, int32 length, LayerData *d) +float ViewDriver::StringWidth(const char *string, int32 length, DrawData *d) { if(!string || !d || !is_initialized) return 0.0; @@ -1089,7 +1098,7 @@ float ViewDriver::StringWidth(const char *string, int32 length, LayerData *d) return returnval; } -float ViewDriver::StringHeight(const char *string, int32 length, LayerData *d) +float ViewDriver::StringHeight(const char *string, int32 length, DrawData *d) { if(!string || !d || !is_initialized) return 0.0; @@ -1146,7 +1155,7 @@ float ViewDriver::StringHeight(const char *string, int32 length, LayerData *d) } */ /* -void ViewDriver::DrawString(const char *string, int32 length, BPoint pt, LayerData *d, escapement_delta *edelta) +void ViewDriver::DrawString(const char *string, int32 length, BPoint pt, DrawData *d, escapement_delta *edelta) { if(!is_initialized) return; @@ -1294,7 +1303,7 @@ void ViewDriver::DrawString(const char *string, int32 length, BPoint pt, LayerDa } */ -void ViewDriver::BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) +void ViewDriver::BlitMono2RGB32(FT_Bitmap *src, BPoint pt, DrawData *d) { if(!is_initialized) return; @@ -1382,7 +1391,7 @@ void ViewDriver::BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) } -void ViewDriver::BlitGray2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) +void ViewDriver::BlitGray2RGB32(FT_Bitmap *src, BPoint pt, DrawData *d) { if(!is_initialized) return; @@ -1499,7 +1508,7 @@ void ViewDriver::BlitGray2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) } } -rgb_color ViewDriver::GetBlitColor(rgb_color src, rgb_color dest, LayerData *d, bool use_high) +rgb_color ViewDriver::GetBlitColor(rgb_color src, rgb_color dest, DrawData *d, bool use_high) { rgb_color returncolor={0,0,0,0}; @@ -1746,3 +1755,108 @@ status_t ViewDriver::WaitForRetrace(bigtime_t timeout=B_INFINITE_TIMEOUT) BScreen screen; return screen.WaitForRetrace(timeout); } + +void ViewDriver::CopyBitmap(ServerBitmap *bitmap, const BRect &source, const BRect &dest, const DrawData *d) +{ + if(!is_initialized || !bitmap || !d) + return; + + SetDrawData(d); + + // Oh, wow, is this going to be slow. Then again, ViewDriver was never meant to be very fast. It could + // be made significantly faster by directly copying from the source to the destination, but that would + // require implementing a lot of code. Eventually, this should be replaced, but for now, using + // DrawBitmap will at least work with a minimum of effort. + + BBitmap *mediator=new BBitmap(bitmap->Bounds(),bitmap->ColorSpace()); + memcpy(mediator->Bits(),bitmap->Bits(),bitmap->BitsLength()); + + screenwin->Lock(); + framebuffer->Lock(); + + drawview->DrawBitmap(mediator,source,dest); + + framebuffer->Unlock(); + screenwin->Unlock(); + delete mediator; +} + +void ViewDriver::CopyToBitmap(ServerBitmap *destbmp, const BRect &sourcerect) +{ + if(!is_initialized || !destbmp) + return; + + if(destbmp->BitsPerPixel() != _buffer_depth) + return; + + BRect destrect(destbmp->Bounds()), source(sourcerect); + + uint8 colorspace_size=destbmp->BitsPerPixel()/8; + + // First, clip source rect to destination + if(source.Width() > destrect.Width()) + source.right=source.left+destrect.Width(); + + + if(source.Height() > destrect.Height()) + source.bottom=source.top+destrect.Height(); + + + // Second, check rectangle bounds against their own bitmaps + BRect work_rect; + + work_rect.Set( destbmp->Bounds().left, + destbmp->Bounds().top, + destbmp->Bounds().right, + destbmp->Bounds().bottom ); + if( !(work_rect.Contains(destrect)) ) + { // something in selection must be clipped + if(destrect.left < 0) + destrect.left = 0; + if(destrect.right > work_rect.right) + destrect.right = work_rect.right; + if(destrect.top < 0) + destrect.top = 0; + if(destrect.bottom > work_rect.bottom) + destrect.bottom = work_rect.bottom; + } + + work_rect.Set(0,0,_displaymode.virtual_width-1,_displaymode.virtual_height-1); + + if( !(work_rect.Contains(source)) ) + { // something in selection must be clipped + if(source.left < 0) + source.left = 0; + if(source.right > work_rect.right) + source.right = work_rect.right; + if(source.top < 0) + source.top = 0; + if(source.bottom > work_rect.bottom) + source.bottom = work_rect.bottom; + } + + // Set pointers to the actual data + uint8 *dest_bits = (uint8*) destbmp->Bits(); + uint8 *src_bits = (uint8*) framebuffer->Bits(); + + // Get row widths for offset looping + uint32 dest_width = uint32 (destbmp->BytesPerRow()); + uint32 src_width = uint32 (framebuffer->BytesPerRow()); + + // Offset bitmap pointers to proper spot in each bitmap + src_bits += uint32 ( (source.top * src_width) + (source.left * colorspace_size) ); + dest_bits += uint32 ( (destrect.top * dest_width) + (destrect.left * colorspace_size) ); + + uint32 line_length = uint32 ((destrect.right - destrect.left+1)*colorspace_size); + uint32 lines = uint32 (destrect.bottom-destrect.top+1); + + for (uint32 pos_y = 0; pos_y != lines; pos_y++) + { + memcpy(dest_bits,src_bits,line_length); + + // Increment offsets + src_bits += src_width; + dest_bits += dest_width; + } + +} diff --git a/src/servers/app/server/ViewDriver.h b/src/servers/app/server/ViewDriver.h index f9b26a36b9..86445e944c 100644 --- a/src/servers/app/server/ViewDriver.h +++ b/src/servers/app/server/ViewDriver.h @@ -42,7 +42,7 @@ class BBitmap; class PortLink; class VDWindow; -class LayerData; +class DrawData; class VDView : public BView { @@ -134,12 +134,14 @@ protected: void FillPatternRect(const BRect &rect, const DrawData *d); void StrokeSolidRect(const BRect &rect, RGBColor &color); void StrokeSolidLine(const BPoint &start, const BPoint &end, RGBColor &color); - void SetLayerData(LayerData *d, bool set_font_data=false); + void SetDrawData(const DrawData *d, bool set_font_data=false); void StrokePatternLine(const BPoint &start, const BPoint &end, const DrawData *d); + void CopyBitmap(ServerBitmap *bitmap, const BRect &source, const BRect &dest, const DrawData *d); + void CopyToBitmap(ServerBitmap *target, const BRect &source); - void BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d); - void BlitGray2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d); - rgb_color GetBlitColor(rgb_color src, rgb_color dest, LayerData *d, bool use_high=true); + void BlitMono2RGB32(FT_Bitmap *src, BPoint pt, DrawData *d); + void BlitGray2RGB32(FT_Bitmap *src, BPoint pt, DrawData *d); + rgb_color GetBlitColor(rgb_color src, rgb_color dest, DrawData *d, bool use_high=true); int hide_cursor; bool obscure_cursor; BBitmap *framebuffer;