offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-07-05 16:17:16 +00:00
parent 31a3ded6f0
commit 359c905c57
36 changed files with 1497 additions and 681 deletions
+1
View File
@@ -110,6 +110,7 @@ class Decorator {
{ return (_colors) ? *_colors : ColorSet(); } { return (_colors) ? *_colors : ColorSet(); }
virtual void GetFootprint(BRegion *region); virtual void GetFootprint(BRegion *region);
virtual click_type Clicked(BPoint pt, int32 buttons, virtual click_type Clicked(BPoint pt, int32 buttons,
int32 modifiers); int32 modifiers);
+30 -24
View File
@@ -24,6 +24,7 @@ class BRect;
class BRegion; class BRegion;
class DrawData; class DrawData;
class HWInterface;
class RGBColor; class RGBColor;
class ServerBitmap; class ServerBitmap;
class ServerCursor; class ServerCursor;
@@ -60,6 +61,8 @@ public:
// call this on mode changes! // call this on mode changes!
virtual void Update() = 0; virtual void Update() = 0;
virtual void SetHWInterface(HWInterface* interface) = 0;
// clipping for all drawing functions // clipping for all drawing functions
virtual void ConstrainClippingRegion(BRegion* region) = 0; virtual void ConstrainClippingRegion(BRegion* region) = 0;
@@ -73,14 +76,14 @@ public:
int32 rCount, int32 rCount,
BRegion* clipReg) = 0; BRegion* clipReg) = 0;
virtual void InvertRect( const BRect &r) = 0; virtual void InvertRect( BRect r) = 0;
virtual void DrawBitmap( ServerBitmap *bitmap, virtual void DrawBitmap( ServerBitmap *bitmap,
const BRect &source, const BRect &source,
const BRect &dest, const BRect &dest,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void FillArc( const BRect &r, virtual void FillArc( BRect r,
const float &angle, const float &angle,
const float &span, const float &span,
const DrawData *d) = 0; const DrawData *d) = 0;
@@ -88,24 +91,24 @@ public:
virtual void FillBezier( BPoint *pts, virtual void FillBezier( BPoint *pts,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void FillEllipse( const BRect &r, virtual void FillEllipse( BRect r,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void FillPolygon( BPoint *ptlist, virtual void FillPolygon( BPoint *ptlist,
int32 numpts, int32 numpts,
const BRect &bounds, BRect bounds,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void FillRect( const BRect &r, virtual void FillRect( BRect r,
const RGBColor &color) = 0; const RGBColor &color) = 0;
virtual void FillRect( const BRect &r, virtual void FillRect( BRect r,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void FillRegion( BRegion &r, virtual void FillRegion( BRegion &r,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void FillRoundRect( const BRect &r, virtual void FillRoundRect( BRect r,
const float &xrad, const float &xrad,
const float &yrad, const float &yrad,
const DrawData *d) = 0; const DrawData *d) = 0;
@@ -118,10 +121,10 @@ public:
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void FillTriangle( BPoint *pts, virtual void FillTriangle( BPoint *pts,
const BRect &bounds, BRect bounds,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void StrokeArc( const BRect &r, virtual void StrokeArc( BRect r,
const float &angle, const float &angle,
const float &span, const float &span,
const DrawData *d) = 0; const DrawData *d) = 0;
@@ -129,7 +132,7 @@ public:
virtual void StrokeBezier( BPoint *pts, virtual void StrokeBezier( BPoint *pts,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void StrokeEllipse( const BRect &r, virtual void StrokeEllipse( BRect r,
const DrawData *d) = 0; const DrawData *d) = 0;
// this version used by Decorator // this version used by Decorator
@@ -154,21 +157,21 @@ public:
virtual void StrokePolygon( BPoint *ptlist, virtual void StrokePolygon( BPoint *ptlist,
int32 numpts, int32 numpts,
const BRect &bounds, BRect bounds,
const DrawData *d, const DrawData *d,
bool is_closed=true) = 0; bool is_closed=true) = 0;
// this version used by Decorator // this version used by Decorator
virtual void StrokeRect( const BRect &r, virtual void StrokeRect( BRect r,
const RGBColor &color) = 0; const RGBColor &color) = 0;
virtual void StrokeRect( const BRect &r, virtual void StrokeRect( BRect r,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void StrokeRegion( BRegion &r, virtual void StrokeRegion( BRegion &r,
const DrawData *d) = 0; const DrawData *d) = 0;
virtual void StrokeRoundRect(const BRect &r, virtual void StrokeRoundRect(BRect r,
const float &xrad, const float &xrad,
const float &yrad, const float &yrad,
const DrawData *d) = 0; const DrawData *d) = 0;
@@ -187,24 +190,27 @@ public:
// Font-related calls // Font-related calls
// DrawData is NOT const because this call updates the pen position in the passed DrawData // DrawData is NOT const because this call updates the pen position in the passed DrawData
virtual void DrawString( const char *string, virtual void DrawString( const char* string,
const int32 &length, int32 length,
const BPoint &pt, const BPoint& pt,
DrawData *d) = 0; DrawData* d,
escapement_delta *delta = NULL) = 0;
virtual void DrawString( const char *string, /* virtual void DrawString( const char *string,
const int32 &length, const int32 &length,
const BPoint &pt, const BPoint &pt,
const RGBColor &color, const RGBColor &color,
escapement_delta *delta=NULL) = 0; escapement_delta *delta = NULL) = 0;*/
virtual float StringWidth( const char *string, virtual float StringWidth( const char* string,
int32 length, int32 length,
const DrawData *d) = 0; const DrawData* d,
escapement_delta *delta = NULL) = 0;
virtual float StringWidth( const char *string, virtual float StringWidth( const char* string,
int32 length, int32 length,
const ServerFont &font) = 0; const ServerFont& font,
escapement_delta *delta = NULL) = 0;
virtual float StringHeight( const char *string, virtual float StringHeight( const char *string,
int32 length, int32 length,
+27 -17
View File
@@ -49,11 +49,11 @@ class DrawData {
public: public:
DrawData(); DrawData();
DrawData(const DrawData& from); DrawData(const DrawData& from);
// used for the State stack, no
// true 1:1 copy!
DrawData(const DrawData* from);
virtual ~DrawData(); virtual ~DrawData();
// NOTE: this operator will not make a 1:1 copy, it is used
// for the state stack and therefor origin and scale are reset
// to B_ORIGIN and 1.0.
DrawData& operator=(const DrawData& from); DrawData& operator=(const DrawData& from);
// coordinate transformation // coordinate transformation
@@ -112,15 +112,10 @@ class DrawData {
inline const ServerFont& Font() const inline const ServerFont& Font() const
{ return fFont; } { return fFont; }
// TODO: remove (is contained in SeverFont::Flags()) // overrides aliasing flag contained in SeverFont::Flags())
void SetFontAntiAliasing(bool antiAliasing); void SetForceFontAliasing(bool aliasing);
inline bool FontAntiAliasing() const inline bool ForceFontAliasing() const
{ return fFontAntiAliasing; } { return fFontAliasing; }
// TODO: remove (should be part of DisplayDriver::DrawString() as in BView)
void SetEscapementDelta(escapement_delta delta);
inline escapement_delta EscapementDelta() const
{ return fEscapementDelta; }
// postscript style settings // postscript style settings
void SetLineCapMode(cap_mode mode); void SetLineCapMode(cap_mode mode);
@@ -139,6 +134,9 @@ class DrawData {
inline BPoint Transform(const BPoint& point) const; inline BPoint Transform(const BPoint& point) const;
inline BRect Transform(const BRect& rect) const; inline BRect Transform(const BRect& rect) const;
void SetSubPixelPrecise(bool precise);
inline bool SubPixelPrecise() const
{ return fSubPixelPrecise; }
protected: protected:
BPoint fOrigin; BPoint fOrigin;
@@ -158,10 +156,19 @@ class DrawData {
float fPenSize; float fPenSize;
ServerFont fFont; ServerFont fFont;
// TODO: Remove, see above // overrides font aliasing flag
bool fFontAntiAliasing; bool fFontAliasing;
escapement_delta fEscapementDelta;
// // This is not part of the normal state stack.
// Layer will update it in PushState/PopState.
// A BView can have a flag "B_SUBPIXEL_PRECISE",
// I never knew what it does on R5, but I can use
// it in Painter to actually draw stuff with
// sub-pixel coordinates. It means
// StrokeLine(BPoint(10, 5), BPoint(20, 9));
// will look different from
// StrokeLine(BPoint(10.3, 5.8), BPoint(20.6, 9.5));
bool fSubPixelPrecise;
cap_mode fLineCapMode; cap_mode fLineCapMode;
join_mode fLineJoinMode; join_mode fLineJoinMode;
@@ -174,7 +181,10 @@ class DrawData {
class LayerData : public DrawData { class LayerData : public DrawData {
public: public:
LayerData(); LayerData();
LayerData(const LayerData &data); LayerData(const LayerData& data);
// this version used for the state
// stack, sets prevState to data too
LayerData(LayerData* data);
virtual ~LayerData(); virtual ~LayerData();
LayerData& operator=(const LayerData &from); LayerData& operator=(const LayerData &from);
@@ -4,6 +4,7 @@
#define RENDERING_BUFFER_H #define RENDERING_BUFFER_H
#include <GraphicsDefs.h> #include <GraphicsDefs.h>
#include <Rect.h>
class RenderingBuffer { class RenderingBuffer {
public: public:
@@ -22,6 +23,11 @@ class RenderingBuffer {
inline uint32 BitsLength() const inline uint32 BitsLength() const
{ return Height() * BytesPerRow(); } { return Height() * BytesPerRow(); }
inline BRect Bounds() const
{ return BRect(0.0, 0.0,
Width() - 1,
Height() - 1); }
}; };
#endif // RENDERING_BUFFER_H #endif // RENDERING_BUFFER_H
+1 -1
View File
@@ -64,7 +64,7 @@
# define DEFAULT_BOLD_FONT_FAMILY "Bitstream Vera Sans" # define DEFAULT_BOLD_FONT_FAMILY "Bitstream Vera Sans"
# define FALLBACK_BOLD_FONT_FAMILY "Swis721 BT" # define FALLBACK_BOLD_FONT_FAMILY "Swis721 BT"
# define DEFAULT_BOLD_FONT_STYLE "Bold" # define DEFAULT_BOLD_FONT_STYLE "Bold"
# define DEFAULT_BOLD_FONT_SIZE 11 # define DEFAULT_BOLD_FONT_SIZE 12
# define DEFAULT_FIXED_FONT_FAMILY "Bitstream Vera Sans Mono" # define DEFAULT_FIXED_FONT_FAMILY "Bitstream Vera Sans Mono"
# define FALLBACK_FIXED_FONT_FAMILY "Courier10 BT" # define FALLBACK_FIXED_FONT_FAMILY "Courier10 BT"
# define DEFAULT_FIXED_FONT_STYLE "Roman" # define DEFAULT_FIXED_FONT_STYLE "Roman"
+1 -1
View File
@@ -332,7 +332,7 @@ MemPool::ReallocateBuffer(void *buf, ssize_t size)
void void
MemPool::ReleaseBuffer(void *buf) MemPool::ReleaseBuffer(void *buf)
{ {
struct bfhead *b, *bn; struct bfhead *b, *bn;
b = BFH(((char *) buf) - sizeof(struct bhead)); b = BFH(((char *) buf) - sizeof(struct bhead));
+1 -1
View File
@@ -341,7 +341,7 @@ DefaultDecorator::_DoLayout()
fTabOffset = 0; fTabOffset = 0;
// distance from one item of the tab bar to another. // distance from one item of the tab bar to another.
// In this case the text and close/zoom rects // In this case the text and close/zoom rects
fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 12 : 20; fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 10 : 18;
font_height fh; font_height fh;
_drawdata.Font().Height(&fh); _drawdata.Font().Height(&fh);
+29 -2
View File
@@ -49,9 +49,32 @@
Desktop::Desktop() Desktop::Desktop()
: fWinBorderList(64),
fWinLock("desktop window list lock"),
fRootLayerList(2),
fActiveRootLayer(NULL),
fScreenList(2),
fActiveScreen(NULL),
fMouseMode(B_NORMAL_MOUSE),
fFFMouseMode(false)
{ {
fActiveRootLayer = NULL; // init scrollbar info
fActiveScreen = NULL; fScrollBarInfo.proportional = true;
fScrollBarInfo.double_arrows = false;
// look of the knob (R5: (0, 1, 2), 1 = default)
fScrollBarInfo.knob = 1;
fScrollBarInfo.min_knob_size = 15;
// init menu info
fMenuInfo.font_size = 12.0;
// TODO: ...
// fMenuInfo.f_family;
// fMenuInfo.f_style;
// fMenuInfo.background_color = gColorSet->menu_background;
// look of the separator (R5: (0, 1, 2), default ?)
fMenuInfo.separator = 0;
fMenuInfo.click_to_open = true;
fMenuInfo.triggers_always_shown = false;
} }
@@ -110,7 +133,11 @@ Desktop::_AddGraphicsCard(HWInterface* interface)
if (screen->Initialize() >= B_OK && fScreenList.AddItem((void*)screen)) { if (screen->Initialize() >= B_OK && fScreenList.AddItem((void*)screen)) {
// TODO: be careful of screen initialization - monitor may not support 640x480 // TODO: be careful of screen initialization - monitor may not support 640x480
#if __HAIKU__
screen->SetMode(1400, 1050, B_RGB32, 60.f);
#else
screen->SetMode(800, 600, B_RGB32, 60.f); screen->SetMode(800, 600, B_RGB32, 60.f);
#endif
} else { } else {
delete screen; delete screen;
+4 -1
View File
@@ -33,7 +33,6 @@ if ( $(TARGET_PLATFORM) = haiku ) {
} else { } else {
VIEW_DRIVER_SOURCES = VIEW_DRIVER_SOURCES =
fake_input_server.cpp fake_input_server.cpp
BBitmapBuffer.cpp
BitmapBuffer.cpp BitmapBuffer.cpp
AccelerantBuffer.cpp AccelerantBuffer.cpp
AccelerantHWInterface.cpp AccelerantHWInterface.cpp
@@ -90,8 +89,12 @@ Server app_server :
# DisplayDriver Classes # DisplayDriver Classes
$(VIEW_DRIVER_SOURCES) $(VIEW_DRIVER_SOURCES)
BBitmapBuffer.cpp
BitmapHWInterface.cpp
DefaultDecorator.cpp DefaultDecorator.cpp
Layer.cpp Layer.cpp
OffscreenServerWindow.cpp
OffscreenWinBorder.cpp
RootLayer.cpp RootLayer.cpp
ServerPicture.cpp ServerPicture.cpp
ServerScreen.cpp ServerScreen.cpp
+40 -12
View File
@@ -61,12 +61,6 @@
# define RBTRACE(x) ; # define RBTRACE(x) ;
#endif #endif
enum {
B_LAYER_ACTION_NONE = 0,
B_LAYER_ACTION_MOVE,
B_LAYER_ACTION_RESIZE
};
Layer::Layer(BRect frame, const char* name, int32 token, Layer::Layer(BRect frame, const char* name, int32 token,
uint32 resize, uint32 flags, DisplayDriver* driver) uint32 resize, uint32 flags, DisplayDriver* driver)
: :
@@ -129,6 +123,19 @@ CRITICAL(helper);
if (!fDriver) if (!fDriver)
CRITICAL("You MUST have a valid driver to init a Layer object\n"); CRITICAL("You MUST have a valid driver to init a Layer object\n");
// NOTE: This flag is forwarded to a LayerData setting, even
// though it is actually not part of a "state". However,
// it is an important detail of a graphics context, and we
// have no other means to pass this setting on to the DisplayDriver
// other than through the LayerData. If we ever add a flag
// B_ANTI_ALIASING to the view flags, it would have to be passed
// in the same way. Though when breaking binary compatibility,
// we might want to make this an actual part of a "state" (with
// a different API to set these).
// Note that the flag is also tested (updated) in Push/PopState and
// SetFlags().
fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
STRACE(("Layer(%s) successfuly created\n", Name())); STRACE(("Layer(%s) successfuly created\n", Name()));
} }
@@ -139,9 +146,6 @@ Layer::~Layer()
// TODO: uncomment! // TODO: uncomment!
//PruneTree(); //PruneTree();
// fServerWin->RemoveChild(fDriver);
// delete fDriver;
} }
/*! /*!
@@ -210,7 +214,7 @@ Layer::AddChild(Layer* layer, ServerWindow* serverWin)
} else { } else {
// go right or up // go right or up
if (c == stop) // out trip is over if (c == stop) // our trip is over
break; break;
if (c->fLowerSibling) { if (c->fLowerSibling) {
@@ -466,6 +470,21 @@ Layer::BottomChild() const
return fCurrent; return fCurrent;
} }
// SetName
void
Layer::SetName(const char* name)
{
fName.SetTo(name);
}
// SetFlags
void
Layer::SetFlags(uint32 flags)
{
fFlags = flags;
fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
}
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
//! Rebuilds the layer's "completely visible" region //! Rebuilds the layer's "completely visible" region
@@ -987,9 +1006,10 @@ Layer::IsHidden(void) const
void void
Layer::PushState() Layer::PushState()
{ {
LayerData *data = new LayerData(*fLayerData); LayerData *data = new LayerData(fLayerData);
data->prevState = fLayerData;
fLayerData = data; fLayerData = data;
fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
} }
@@ -1005,6 +1025,8 @@ Layer::PopState()
fLayerData = fLayerData->prevState; fLayerData = fLayerData->prevState;
data->prevState = NULL; data->prevState = NULL;
delete data; delete data;
fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
} }
@@ -1762,6 +1784,12 @@ Layer::do_CopyBits(BRect& src, BRect& dst, int32 xOffset, int32 yOffset) {
// are triggering BView::Draw() to be called // are triggering BView::Draw() to be called
// and for these parts only. // and for these parts only.
// TODO: having moved this into Layer broke
// offscreen windows (bitmaps)
// -> move back into ServerWindow...
if (!GetRootLayer())
return;
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
// the region that is going to be copied // the region that is going to be copied
+16 -4
View File
@@ -51,6 +51,12 @@ enum {
B_LAYER_MASK_RESIZE = 5, B_LAYER_MASK_RESIZE = 5,
}; };
enum {
B_LAYER_ACTION_NONE = 0,
B_LAYER_ACTION_MOVE,
B_LAYER_ACTION_RESIZE
};
enum { enum {
B_LAYER_CHILDREN_DEPENDANT = 0x1000U, B_LAYER_CHILDREN_DEPENDANT = 0x1000U,
}; };
@@ -91,14 +97,18 @@ class Layer {
virtual Layer* LowerSibling() const; virtual Layer* LowerSibling() const;
virtual Layer* UpperSibling() const; virtual Layer* UpperSibling() const;
virtual Layer* BottomChild() const; virtual Layer* BottomChild() const;
const char* Name() const virtual void SetName(const char* name);
inline const char* Name() const
{ return fName.String(); } { return fName.String(); }
inline uint32 Flags() const
{ return fFlags; }
inline uint32 ResizeMode() const inline uint32 ResizeMode() const
{ return fResizeMode; } { return fResizeMode; }
virtual void SetFlags(uint32 flags);
inline uint32 Flags() const
{ return fFlags; }
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
virtual void RebuildFullRegion(); virtual void RebuildFullRegion();
void StartRebuildRegions(const BRegion& reg, void StartRebuildRegions(const BRegion& reg,
@@ -276,6 +286,8 @@ class Layer {
friend class RootLayer; friend class RootLayer;
friend class WinBorder; friend class WinBorder;
friend class ServerWindow; friend class ServerWindow;
// TODO: remove, is here for debugging purposes only
friend class OffscreenWinBorder;
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
void move_layer(float x, float y); void move_layer(float x, float y);
+62 -34
View File
@@ -35,7 +35,8 @@ DrawData::DrawData()
fPenLocation(0.0, 0.0), fPenLocation(0.0, 0.0),
fPenSize(1.0), fPenSize(1.0),
fFont(), fFont(),
fFontAntiAliasing(true), fFontAliasing(false),
fSubPixelPrecise(false),
fLineCapMode(B_BUTT_CAP), fLineCapMode(B_BUTT_CAP),
fLineJoinMode(B_BEVEL_JOIN), fLineJoinMode(B_BEVEL_JOIN),
fMiterLimit(B_DEFAULT_MITER_LIMIT) fMiterLimit(B_DEFAULT_MITER_LIMIT)
@@ -43,9 +44,6 @@ DrawData::DrawData()
if (gFontServer && gFontServer->GetSystemPlain()) if (gFontServer && gFontServer->GetSystemPlain())
fFont = *(gFontServer->GetSystemPlain()); fFont = *(gFontServer->GetSystemPlain());
fEscapementDelta.space = 0;
fEscapementDelta.nonspace = 0;
fUnscaledFontSize = fFont.Size(); fUnscaledFontSize = fFont.Size();
} }
@@ -56,6 +54,42 @@ DrawData::DrawData(const DrawData& from)
*this = from; *this = from;
} }
// copy constructor
DrawData::DrawData(const DrawData* from)
: fOrigin(0.0, 0.0),
fScale(1.0),
fClippingRegion(NULL)
{
if (from->fClippingRegion) {
SetClippingRegion(*(from->fClippingRegion));
}
fHighColor = from->fHighColor;
fLowColor = from->fLowColor;
fPattern = from->fPattern;
fDrawingMode = from->fDrawingMode;
fAlphaSrcMode = from->fAlphaSrcMode;
fAlphaFncMode = from->fAlphaFncMode;
fPenLocation = from->fPenLocation;
fPenSize = from->fPenSize;
fFont = from->fFont;
fFontAliasing = from->fFontAliasing;
fSubPixelPrecise = from->fSubPixelPrecise;
fLineCapMode = from->fLineCapMode;
fLineJoinMode = from->fLineJoinMode;
fMiterLimit = from->fMiterLimit;
// Since fScale is reset to 1.0, the unscaled
// font size is the current size of the font
// (which is from->fUnscaledFontSize * from->fScale)
fUnscaledFontSize = fFont.Size();
}
// destructor // destructor
DrawData::~DrawData() DrawData::~DrawData()
{ {
@@ -66,16 +100,8 @@ DrawData::~DrawData()
DrawData& DrawData&
DrawData::operator=(const DrawData& from) DrawData::operator=(const DrawData& from)
{ {
// NOTE: This function is intended for use by the Layer fOrigin = from.fOrigin;
// state stack only. fScale = from.fScale;
// So it does not make a true copy of the DrawData, but resets
// fOrigin and fScale and uses the current the font size as
// fUnscaledFontSize.
// fOrigin = from.fOrigin;
// fScale = from.fScale;
fOrigin = BPoint(0.0, 0.0);
fScale = 1.0;
if (from.fClippingRegion) { if (from.fClippingRegion) {
SetClippingRegion(*(from.fClippingRegion)); SetClippingRegion(*(from.fClippingRegion));
@@ -96,18 +122,15 @@ DrawData::operator=(const DrawData& from)
fPenSize = from.fPenSize; fPenSize = from.fPenSize;
fFont = from.fFont; fFont = from.fFont;
fFontAntiAliasing = from.fFontAntiAliasing; fFontAliasing = from.fFontAliasing;
fEscapementDelta = from.fEscapementDelta;
fSubPixelPrecise = from.fSubPixelPrecise;
fLineCapMode = from.fLineCapMode; fLineCapMode = from.fLineCapMode;
fLineJoinMode = from.fLineJoinMode; fLineJoinMode = from.fLineJoinMode;
fMiterLimit = from.fMiterLimit; fMiterLimit = from.fMiterLimit;
// fUnscaledFontSize = from.fUnscaledFontSize; fUnscaledFontSize = from.fUnscaledFontSize;
// Since fScale is reset to 1.0, the unscaled
// font size is the current size of the font
// (which is from.fFont.Size() * from.fScale)
fUnscaledFontSize = fFont.Size();
return *this; return *this;
} }
@@ -269,18 +292,18 @@ DrawData::SetFont(const ServerFont& font, uint32 flags)
} }
} }
// SetFontAntiAliasing // SetForceFontAliasing
void void
DrawData::SetFontAntiAliasing(bool antiAliasing) DrawData::SetForceFontAliasing(bool aliasing)
{ {
fFontAntiAliasing = antiAliasing; fFontAliasing = aliasing;
} }
// SetEscapementDelta // SetSubPixelPrecise
void void
DrawData::SetEscapementDelta(escapement_delta delta) DrawData::SetSubPixelPrecise(bool precise)
{ {
fEscapementDelta = delta; fSubPixelPrecise = precise;
} }
// SetLineCapMode // SetLineCapMode
@@ -315,12 +338,20 @@ LayerData::LayerData()
} }
// LayerData // LayerData
LayerData::LayerData(const LayerData &data) LayerData::LayerData(const LayerData& data)
: DrawData()
{ {
fClippingRegion = NULL; fClippingRegion = NULL;
*this = data; *this = data;
} }
// LayerData
LayerData::LayerData(LayerData* data)
: DrawData(data),
prevState(data)
{
}
// destructor // destructor
LayerData::~LayerData() LayerData::~LayerData()
{ {
@@ -333,7 +364,7 @@ LayerData::operator=(const LayerData& from)
{ {
DrawData::operator=(from); DrawData::operator=(from);
prevState = from.prevState; prevState = from.prevState;
return *this; return *this;
} }
@@ -450,10 +481,7 @@ LayerData::ReadFromLink(BPrivate::LinkReceiver& link)
link.Read<int8>((int8*)&fAlphaSrcMode); link.Read<int8>((int8*)&fAlphaSrcMode);
link.Read<int8>((int8*)&fAlphaFncMode); link.Read<int8>((int8*)&fAlphaFncMode);
link.Read<float>(&fScale); link.Read<float>(&fScale);
link.Read<bool>(&fFontAntiAliasing); link.Read<bool>(&fFontAliasing);
// TODO: ahm... which way arround?
fFontAntiAliasing = !fFontAntiAliasing;
fHighColor = highColor; fHighColor = highColor;
fLowColor = lowColor; fLowColor = lowColor;
@@ -505,7 +533,7 @@ LayerData::WriteToLink(BPrivate::LinkSender& link) const
link.Attach<uint8>((uint8)fAlphaSrcMode); link.Attach<uint8>((uint8)fAlphaSrcMode);
link.Attach<uint8>((uint8)fAlphaFncMode); link.Attach<uint8>((uint8)fAlphaFncMode);
link.Attach<float>(fScale); link.Attach<float>(fScale);
link.Attach<bool>(!fFontAntiAliasing); link.Attach<bool>(fFontAliasing);
int32 clippingRectCount = fClippingRegion ? fClippingRegion->CountRects() : 0; int32 clippingRectCount = fClippingRegion ? fClippingRegion->CountRects() : 0;
link.Attach<int32>(clippingRectCount); link.Attach<int32>(clippingRectCount);
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright 2005, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "OffscreenWinBorder.h"
#include "ServerBitmap.h"
#include "OffscreenServerWindow.h"
// constructor
OffscreenServerWindow::OffscreenServerWindow(const char *title,
ServerApp *app,
port_id clientPort,
port_id looperPort,
int32 handlerID,
ServerBitmap* bitmap)
: ServerWindow(title, app, clientPort, looperPort, handlerID),
fBitmap(bitmap)
{
}
// destructor
OffscreenServerWindow::~OffscreenServerWindow()
{
}
// SendMessageToClient
void
OffscreenServerWindow::SendMessageToClient(const BMessage* msg, int32 target,
bool usePreferred) const
{
// We're a special kind of window. The client BWindow thread is not running,
// so we cannot post messages to the client. In order to not mess arround
// with all the other code, we simply make this function virtual and
// don't do anything in this implementation.
}
// MakeWinBorder
WinBorder*
OffscreenServerWindow::MakeWinBorder(BRect frame, const char* name,
uint32 look, uint32 feel, uint32 flags,
uint32 workspace)
{
return new OffscreenWinBorder(fBitmap, name, this);
}
+37
View File
@@ -0,0 +1,37 @@
/*
* Copyright 2005, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef OFFSCREEN_SERVER_WINDOW_H
#define OFFSCREEN_SERVER_WINDOW_H
#include "ServerWindow.h"
class OffscreenServerWindow : public ServerWindow {
public:
OffscreenServerWindow(const char *title,
ServerApp *app,
port_id clientPort,
port_id looperPort,
int32 handlerID,
ServerBitmap* bitmap);
virtual ~OffscreenServerWindow();
// util methods.
virtual void SendMessageToClient(const BMessage* msg,
int32 target = B_NULL_TOKEN,
bool usePreferred = false) const;
virtual WinBorder* MakeWinBorder(BRect frame,
const char* name,
uint32 look, uint32 feel,
uint32 flags, uint32 workspace);
private:
ServerBitmap* fBitmap;
};
#endif // OFFSCREEN_SERVER_WINDOW_H
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright 2005, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT license.
*
* Author: Stephan Aßmus <superstippi@gmx.de>
*/
#include <stdio.h>
#include <Debug.h>
#include "DebugInfoManager.h"
#include "BitmapHWInterface.h"
#include "DisplayDriverPainter.h"
#include "ServerBitmap.h"
#include "OffscreenWinBorder.h"
// constructor
OffscreenWinBorder::OffscreenWinBorder(ServerBitmap* bitmap,
const char* name,
ServerWindow* window)
: WinBorder(bitmap->Bounds(), name,
B_NO_BORDER_WINDOW_LOOK,
B_NORMAL_WINDOW_FEEL,
0, 0, window,
new DisplayDriverPainter()),
fBitmap(bitmap),
fHWInterface(new BitmapHWInterface(fBitmap))
{
fDriver->SetHWInterface(fHWInterface);
fDriver->Initialize();
fDriver->Update();
#ifndef NEW_CLIPPING
fFull.Set(fFrame);
#endif
}
// destructor
OffscreenWinBorder::~OffscreenWinBorder()
{
fHWInterface->WriteLock();
// Unlike normal Layers, we own the DisplayDriver instance
fDriver->Shutdown();
delete fDriver;
fHWInterface->Shutdown();
fHWInterface->WriteUnlock();
delete fHWInterface;
}
void
OffscreenWinBorder::Draw(const BRect &r)
{
// Nothing to do here
}
void
OffscreenWinBorder::MoveBy(float x, float y)
{
// Nothing to do here
}
void
OffscreenWinBorder::ResizeBy(float x, float y)
{
// Nothing to do here
}
// SetTopLayer
void
OffscreenWinBorder::SetTopLayer(Layer* layer)
{
WinBorder::SetTopLayer(layer);
#ifndef NEW_CLIPPING
fTopLayer->fFull.Set(fFrame.OffsetToCopy(0.0, 0.0));
fTopLayer->fHidden = false;
fTopLayer->fVisible = fTopLayer->fFull;
#endif
}
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright 2005, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT license.
*
* Author: Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef OFFSCREEN_WINBORDER_H
#define OFFSCREEN_WINBORDER_H
#include "WinBorder.h"
class BitmapHWInterface;
class ServerBitmap;
class OffscreenWinBorder : public WinBorder {
public:
OffscreenWinBorder(ServerBitmap* bitmap,
const char* name,
ServerWindow* window);
virtual ~OffscreenWinBorder();
virtual void Draw(const BRect &r);
virtual void MoveBy(float x, float y);
virtual void ResizeBy(float x, float y);
virtual bool IsOffscreenWindow() const
{ return true; }
virtual void SetTopLayer(Layer* layer);
private:
ServerBitmap* fBitmap;
BitmapHWInterface* fHWInterface;
};
#endif
+1 -2
View File
@@ -238,9 +238,8 @@ status_t PicturePlayer::Play(int32 tableEntries,void *userData, LayerData *d)
escapement_delta delta; escapement_delta delta;
delta.nonspace = deltax; delta.nonspace = deltax;
delta.space = deltay; delta.space = deltay;
fldata.SetEscapementDelta(delta);
fdriver->DrawString(string, len, fldata.PenLocation(), &fldata); fdriver->DrawString(string, len, fldata.PenLocation(), &fldata, &delta);
delete string; delete string;
break; break;
} }
+95 -14
View File
@@ -33,8 +33,8 @@
#include "FontServer.h" #include "FontServer.h"
#include "HWInterface.h" #include "HWInterface.h"
#include "LayerData.h" #include "LayerData.h"
#include "OffscreenServerWindow.h"
#include "RAMLinkMsgReader.h" #include "RAMLinkMsgReader.h"
//#include "RGBColor.h"
#include "RootLayer.h" #include "RootLayer.h"
#include "ServerBitmap.h" #include "ServerBitmap.h"
#include "ServerConfig.h" #include "ServerConfig.h"
@@ -165,7 +165,11 @@ ServerApp::~ServerApp(void)
if (tries < 0) { if (tries < 0) {
// This really shouldn't happen, as it shows we're buggy // This really shouldn't happen, as it shows we're buggy
#if __HAIKU__
syslog(LOG_ERR, "ServerApp %s needs to kill some server windows...\n", Signature()); syslog(LOG_ERR, "ServerApp %s needs to kill some server windows...\n", Signature());
#else
fprintf(stderr, "ServerApp %s needs to kill some server windows...\n", Signature());
#endif
// there still seem to be some windows left - kill them! // there still seem to be some windows left - kill them!
fWindowListLock.Lock(); fWindowListLock.Lock();
@@ -187,7 +191,7 @@ ServerApp::~ServerApp(void)
} }
for (int32 i = 0; i < fPictureList.CountItems(); i++) { for (int32 i = 0; i < fPictureList.CountItems(); i++) {
delete static_cast<ServerPicture *>(fPictureList.ItemAt(i)); delete (ServerPicture*)fPictureList.ItemAt(i);
} }
// although this isn't pretty, ATM we have only one RootLayer. // although this isn't pretty, ATM we have only one RootLayer.
@@ -409,7 +413,10 @@ ServerApp::_MessageLooper()
case AS_CREATE_WINDOW: case AS_CREATE_WINDOW:
{ {
// Create the ServerWindow to node monitor a new OBWindow // Create a ServerWindow
// NOTE/TODO: Code duplication in part to below case.
// Watch out, if you make changes here, you might have to do them below.
// Go ahead and fix if you have an idea for unification...
// Attached data: // Attached data:
// 2) BRect window frame // 2) BRect window frame
@@ -450,12 +457,13 @@ ServerApp::_MessageLooper()
// ServerWindow constructor will reply with port_id of a newly created port // ServerWindow constructor will reply with port_id of a newly created port
ServerWindow *window = new ServerWindow(title, this, clientReplyPort, ServerWindow *window = new ServerWindow(title, this, clientReplyPort,
looperPort, token, frame, look, feel, flags, workspaces); looperPort, token);
STRACE(("\nServerApp %s: New Window %s (%.1f,%.1f,%.1f,%.1f)\n", STRACE(("\nServerApp %s: New Window %s (%.1f,%.1f,%.1f,%.1f)\n",
fSignature(), title, frame.left, frame.top, frame.right, frame.bottom)); fSignature(), title, frame.left, frame.top, frame.right, frame.bottom));
if (window->InitCheck() == B_OK && window->Run()) { // NOTE: the reply to the client is handled in window->Run()
if (window->Init(frame, look, feel, flags, workspaces) >= B_OK && window->Run()) {
// add the window to the list // add the window to the list
if (fWindowListLock.Lock()) { if (fWindowListLock.Lock()) {
fWindowList.AddItem(window); fWindowList.AddItem(window);
@@ -473,6 +481,80 @@ ServerApp::_MessageLooper()
// We don't have to free the title, as it's owned by the ServerWindow now // We don't have to free the title, as it's owned by the ServerWindow now
break; break;
} }
case AS_CREATE_OFFSCREEN_WINDOW:
{
// Create an OffscreenServerWindow
// NOTE/TODO: Code duplication in part to above case.
// Attached data:
// 2) BRect window frame
// 3) uint32 window look
// 4) uint32 window feel
// 5) uint32 window flags
// 6) uint32 workspace index
// 7) int32 BHandler token of the window
// 8) port_id window's message port
// 9) const char * title
BRect frame;
int32 bitmapToken;
uint32 look;
uint32 feel;
uint32 flags;
uint32 workspaces;
int32 token = B_NULL_TOKEN;
port_id clientReplyPort = -1;
port_id looperPort = -1;
char *title = NULL;
receiver.Read<int32>(&bitmapToken);
receiver.Read<BRect>(&frame);
receiver.Read<uint32>(&look);
receiver.Read<uint32>(&feel);
receiver.Read<uint32>(&flags);
receiver.Read<uint32>(&workspaces);
receiver.Read<int32>(&token);
receiver.Read<port_id>(&clientReplyPort);
receiver.Read<port_id>(&looperPort);
if (receiver.ReadString(&title) != B_OK)
break;
if (!frame.IsValid()) {
// make sure we pass a valid rectangle to ServerWindow
frame.right = frame.left + 1;
frame.bottom = frame.top + 1;
}
ServerBitmap* bitmap = FindBitmap(bitmapToken);
bool success = false;
if (bitmap) {
// ServerWindow constructor will reply with port_id of a newly created port
OffscreenServerWindow *window = new OffscreenServerWindow(title, this, clientReplyPort,
looperPort, token, bitmap);
// NOTE: the reply to the client is handled in window->Run()
success = window->Init(frame, look, feel, flags, workspaces) >= B_OK && window->Run();
// add the window to the list
if (success && fWindowListLock.Lock()) {
success = fWindowList.AddItem(window);
fWindowListLock.Unlock();
}
if (!success)
delete window;
}
if (!success) {
// window creation failed, we need to notify the client
BPrivate::LinkSender reply(clientReplyPort);
reply.StartMessage(SERVER_FALSE);
reply.Flush();
}
// We don't have to free the title, as it's owned by the ServerWindow now
break;
}
case AS_QUIT_APP: case AS_QUIT_APP:
{ {
@@ -772,14 +854,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<int32>(&bytesPerRow); link.Read<int32>(&bytesPerRow);
if (link.Read<screen_id>(&screenID) == B_OK) { if (link.Read<screen_id>(&screenID) == B_OK) {
bitmap = gBitmapManager->CreateBitmap(frame, colorSpace, flags, bitmap = gBitmapManager->CreateBitmap(frame, colorSpace, flags,
bytesPerRow, screenID); bytesPerRow, screenID);
} }
STRACE(("ServerApp %s: Create Bitmap (%.1fx%.1f)\n", STRACE(("ServerApp %s: Create Bitmap (%.1fx%.1f)\n",
Signature(), frame.Width(), frame.Height())); Signature(), frame.Width(), frame.Height()));
if (bitmap) { if (bitmap && fBitmapList.AddItem((void*)bitmap)) {
fBitmapList.AddItem(bitmap);
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fLink.Attach<int32>(bitmap->Token()); fLink.Attach<int32>(bitmap->Token());
fLink.Attach<int32>(bitmap->Area()); fLink.Attach<int32>(bitmap->Area());
@@ -807,10 +888,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<int32>(&id); link.Read<int32>(&id);
ServerBitmap *bitmap = FindBitmap(id); ServerBitmap *bitmap = FindBitmap(id);
if (bitmap) { if (bitmap && fBitmapList.RemoveItem((void*)bitmap)) {
STRACE(("ServerApp %s: Deleting Bitmap %ld\n", Signature(), id)); STRACE(("ServerApp %s: Deleting Bitmap %ld\n", Signature(), id));
fBitmapList.RemoveItem(bitmap);
gBitmapManager->DeleteBitmap(bitmap); gBitmapManager->DeleteBitmap(bitmap);
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
} else } else
@@ -2141,11 +2221,12 @@ ServerApp::CountBitmaps() const
\param token ID token of the bitmap to find \param token ID token of the bitmap to find
\return The bitmap having that ID or NULL if not found \return The bitmap having that ID or NULL if not found
*/ */
ServerBitmap * ServerBitmap*
ServerApp::FindBitmap(int32 token) const ServerApp::FindBitmap(int32 token) const
{ {
for (int32 i = 0; i < fBitmapList.CountItems(); i++) { int32 count = fBitmapList.CountItems();
ServerBitmap *bitmap = static_cast<ServerBitmap *>(fBitmapList.ItemAt(i)); for (int32 i = 0; i < count; i++) {
ServerBitmap* bitmap = (ServerBitmap*)fBitmapList.ItemAt(i);
if (bitmap && bitmap->Token() == token) if (bitmap && bitmap->Token() == token)
return bitmap; return bitmap;
} }
+207 -108
View File
@@ -10,6 +10,7 @@
* Axel Dörfler, axeld@pinc-software.de * Axel Dörfler, axeld@pinc-software.de
*/ */
#include <new>
#include <AppDefs.h> #include <AppDefs.h>
#include <GraphicsDefs.h> #include <GraphicsDefs.h>
@@ -71,8 +72,7 @@ static const uint32 kMsgWindowQuit = 'winQ';
monitor thread. monitor thread.
*/ */
ServerWindow::ServerWindow(const char *title, ServerApp *app, ServerWindow::ServerWindow(const char *title, ServerApp *app,
port_id clientPort, port_id looperPort, int32 handlerID, port_id clientPort, port_id looperPort, int32 handlerID)
BRect frame, uint32 look, uint32 feel, uint32 flags, uint32 workspace)
: BLocker(title && *title ? title : "Unnamed Window"), : BLocker(title && *title ? title : "Unnamed Window"),
fTitle(title), fTitle(title),
fServerApp(app), fServerApp(app),
@@ -87,27 +87,6 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app,
fCurrentLayer(NULL) fCurrentLayer(NULL)
{ {
STRACE(("ServerWindow(%s)::ServerWindow()\n", title)); STRACE(("ServerWindow(%s)::ServerWindow()\n", title));
if (fTitle == NULL)
fTitle = strdup("Unnamed Window");
if (fTitle == NULL)
return;
// fMessagePort is the port to which the app sends messages for the server
fMessagePort = create_port(100, fTitle);
if (fMessagePort < B_OK)
return;
fLink.SetSenderPort(fClientReplyPort);
fLink.SetReceiverPort(fMessagePort);
char name[60];
snprintf(name, sizeof(name), "%ld: %s", fClientTeam, fTitle);
fWinBorder = new WinBorder(frame, name, look, feel, flags,
workspace, this, gDesktop->GetDisplayDriver());
STRACE(("ServerWindow %s Created\n", fTitle));
} }
@@ -116,7 +95,11 @@ ServerWindow::~ServerWindow()
{ {
STRACE(("*ServerWindow (%s):~ServerWindow()\n", fTitle)); STRACE(("*ServerWindow (%s):~ServerWindow()\n", fTitle));
if (!fWinBorder->IsOffscreenWindow())
gDesktop->RemoveWinBorder(fWinBorder);
delete fWinBorder; delete fWinBorder;
free(const_cast<char *>(fTitle)); free(const_cast<char *>(fTitle));
STRACE(("#ServerWindow(%s) will exit NOW\n", fTitle)); STRACE(("#ServerWindow(%s) will exit NOW\n", fTitle));
@@ -124,14 +107,32 @@ ServerWindow::~ServerWindow()
status_t status_t
ServerWindow::InitCheck() ServerWindow::Init(BRect frame, uint32 look, uint32 feel, uint32 flags, uint32 workspace)
{ {
if (fTitle == NULL || fWinBorder == NULL) if (fTitle == NULL)
fTitle = strdup("Unnamed Window");
if (fTitle == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
// fMessagePort is the port to which the app sends messages for the server
fMessagePort = create_port(100, fTitle);
if (fMessagePort < B_OK) if (fMessagePort < B_OK)
return fMessagePort; return fMessagePort;
fLink.SetSenderPort(fClientReplyPort);
fLink.SetReceiverPort(fMessagePort);
// char name[60];
// snprintf(name, sizeof(name), "%ld: %s", fClientTeam, fTitle);
// We cannot call MakeWinBorder in the constructor, since it
fWinBorder = MakeWinBorder(frame, fTitle, look, feel, flags, workspace);
if (!fWinBorder)
return B_NO_MEMORY;
if (!fWinBorder->IsOffscreenWindow())
gDesktop->AddWinBorder(fWinBorder);
return B_OK; return B_OK;
} }
@@ -379,7 +380,7 @@ ServerWindow::CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent)
&& (fWinBorder->WindowFlags() & 0x00008000) != 0) { && (fWinBorder->WindowFlags() & 0x00008000) != 0) {
// this is a workspaces window! // this is a workspaces window!
newLayer = new WorkspacesLayer(frame, name, token, resizeMask, newLayer = new WorkspacesLayer(frame, name, token, resizeMask,
flags, gDesktop->GetDisplayDriver()); flags, fWinBorder->GetDisplayDriver());
} else { } else {
newLayer = new Layer(frame, name, token, resizeMask, newLayer = new Layer(frame, name, token, resizeMask,
flags, gDesktop->GetDisplayDriver()); flags, gDesktop->GetDisplayDriver());
@@ -394,6 +395,16 @@ ServerWindow::CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent)
newLayer->fEventOptions = eventOptions; newLayer->fEventOptions = eventOptions;
newLayer->fOwner = fWinBorder; newLayer->fOwner = fWinBorder;
// TODO: rework the clipping stuff to remove RootLayer dependency and then
// remove this hack:
if (fWinBorder->IsOffscreenWindow()) {
#ifndef NEW_CLIPPING
newLayer->fVisible.Set(newLayer->fFrame);
#else
newLayer->fVisible2.Set(newLayer->fFrame);
#endif
}
if (_parent) { if (_parent) {
Layer *parent = fWinBorder->FindLayer(parentToken); Layer *parent = fWinBorder->FindLayer(parentToken);
if (parent == NULL) if (parent == NULL)
@@ -415,7 +426,9 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
} }
RootLayer *myRootLayer = fWinBorder->GetRootLayer(); RootLayer *myRootLayer = fWinBorder->GetRootLayer();
myRootLayer->Lock(); // NOTE: is NULL when fWinBorder is offscreen!
if (myRootLayer)
myRootLayer->Lock();
switch (code) { switch (code) {
//--------- BView Messages ----------------- //--------- BView Messages -----------------
@@ -481,9 +494,7 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<int32>(&token); link.Read<int32>(&token);
myRootLayer->Lock();
Layer *current = fWinBorder->FindLayer(token); Layer *current = fWinBorder->FindLayer(token);
myRootLayer->Unlock();
if (current) { if (current) {
DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: %s, token %ld\n", fTitle, current->Name(), token)); DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: %s, token %ld\n", fTitle, current->Name(), token));
} else { } else {
@@ -507,14 +518,8 @@ myRootLayer->Unlock();
if (fCurrentLayer != NULL) if (fCurrentLayer != NULL)
break; break;
myRootLayer->Lock(); fWinBorder->SetTopLayer(CreateLayerTree(link, NULL));
fWinBorder->fTopLayer = CreateLayerTree(link, NULL); fCurrentLayer = fWinBorder->TopLayer();
fWinBorder->fTopLayer->SetAsTopLayer(true);
fCurrentLayer = fWinBorder->fTopLayer;
// connect decorator and top layer.
fWinBorder->AddChild(fWinBorder->fTopLayer, NULL);
myRootLayer->Unlock();
break; break;
} }
@@ -524,11 +529,10 @@ myRootLayer->Unlock();
Layer* parent = NULL; Layer* parent = NULL;
Layer* newLayer = CreateLayerTree(link, &parent); Layer* newLayer = CreateLayerTree(link, &parent);
myRootLayer->Lock();
if (parent != NULL) if (parent != NULL)
parent->AddChild(newLayer, this); parent->AddChild(newLayer, this);
if (!newLayer->IsHidden() && parent) if (myRootLayer && !newLayer->IsHidden() && parent)
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
myRootLayer->GoInvalidate(newLayer, newLayer->fFull); myRootLayer->GoInvalidate(newLayer, newLayer->fFull);
#else #else
@@ -538,8 +542,6 @@ myRootLayer->Lock();
myRootLayer->GoInvalidate(newLayer, invalidRegion); myRootLayer->GoInvalidate(newLayer, invalidRegion);
} }
#endif #endif
myRootLayer->Unlock();
break; break;
} }
case AS_LAYER_DELETE: case AS_LAYER_DELETE:
@@ -568,11 +570,10 @@ myRootLayer->Lock();
fCurrentLayer->RemoveSelf(); fCurrentLayer->RemoveSelf();
fCurrentLayer->PruneTree(); fCurrentLayer->PruneTree();
if (invalidRegion) { if (invalidRegion && myRootLayer) {
myRootLayer->GoInvalidate(parent, *invalidRegion); myRootLayer->GoInvalidate(parent, *invalidRegion);
delete invalidRegion; delete invalidRegion;
} }
myRootLayer->Unlock();
#ifdef DEBUG_SERVERWINDOW #ifdef DEBUG_SERVERWINDOW
parent->PrintTree(); parent->PrintTree();
@@ -627,7 +628,8 @@ myRootLayer->Unlock();
link.Read<uint32>(&mask); link.Read<uint32>(&mask);
link.Read<uint32>(&options); link.Read<uint32>(&options);
myRootLayer->SetEventMaskLayer(fCurrentLayer, mask, options); if (myRootLayer)
myRootLayer->SetEventMaskLayer(fCurrentLayer, mask, options);
break; break;
} }
case AS_LAYER_MOVE_TO: case AS_LAYER_MOVE_TO:
@@ -713,7 +715,9 @@ myRootLayer->Unlock();
} }
case AS_LAYER_SET_FLAGS: case AS_LAYER_SET_FLAGS:
{ {
link.Read<uint32>(&(fCurrentLayer->fFlags)); uint32 flags;
link.Read<uint32>(&flags);
fCurrentLayer->SetFlags(flags);
STRACE(("ServerWindow %s: Message AS_LAYER_SET_FLAGS: Layer: %s\n", Title(), fCurrentLayer->Name())); STRACE(("ServerWindow %s: Message AS_LAYER_SET_FLAGS: Layer: %s\n", Title(), fCurrentLayer->Name()));
break; break;
@@ -858,7 +862,8 @@ myRootLayer->Lock();
fCurrentLayer->SetViewColor(RGBColor(c)); fCurrentLayer->SetViewColor(RGBColor(c));
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible); if (myRootLayer)
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible);
#else #else
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion()); myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion());
#endif #endif
@@ -941,7 +946,7 @@ myRootLayer->Unlock();
DTRACE(("ServerWindow %s: Message AS_LAYER_PRINT_ALIASING: Layer: %s\n", Title(), fCurrentLayer->Name())); DTRACE(("ServerWindow %s: Message AS_LAYER_PRINT_ALIASING: Layer: %s\n", Title(), fCurrentLayer->Name()));
bool fontAliasing; bool fontAliasing;
link.Read<bool>(&fontAliasing); link.Read<bool>(&fontAliasing);
fCurrentLayer->fLayerData->SetFontAntiAliasing(!fontAliasing); fCurrentLayer->fLayerData->SetForceFontAliasing(fontAliasing);
break; break;
} }
@@ -976,7 +981,7 @@ myRootLayer->Unlock();
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
fCurrentLayer->RebuildFullRegion(); fCurrentLayer->RebuildFullRegion();
#endif #endif
if (!(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate()) if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull); myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull);
#else #else
@@ -998,15 +1003,16 @@ myRootLayer->Unlock();
if (fCurrentLayer->IsHidden()) { if (fCurrentLayer->IsHidden()) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fLink.Attach<int32>(0L); fLink.Attach<int32>(0L);
fLink.Flush();
} else { } else {
// TODO: Watch out for the coordinate system in AS_LAYER_GET_CLIP_REGION // TODO: Watch out for the coordinate system in AS_LAYER_GET_CLIP_REGION
LayerData* layerData = fCurrentLayer->fLayerData;
BRegion region; BRegion region;
// TODO: This could also be done more reliably in the Layer, // TODO: This could also be done more reliably in the Layer,
// when the State stack is implemented there. There should be // when the State stack is implemented there. There should be
// DrawData::fCulmulatedClippingRegion... // DrawData::fCulmulatedClippingRegion...
// TODO: the DrawData clipping region should be in local view coords. // TODO: the DrawData clipping region should be in local view coords.
LayerData* layerData = fCurrentLayer->fLayerData;
do { do {
if (layerData->ClippingRegion()) if (layerData->ClippingRegion())
@@ -1020,9 +1026,10 @@ myRootLayer->Unlock();
for (int32 i = 0; i < rectCount; i++) for (int32 i = 0; i < rectCount; i++)
fLink.Attach<BRect>(region.RectAt(i)); fLink.Attach<BRect>(region.RectAt(i));
fLink.Flush();
} }
fLink.Flush();
break; break;
} }
case AS_LAYER_SET_CLIP_REGION: case AS_LAYER_SET_CLIP_REGION:
@@ -1041,16 +1048,16 @@ myRootLayer->Unlock();
region.Include(r); region.Include(r);
} }
fCurrentLayer->fLayerData->SetClippingRegion(region); fCurrentLayer->fLayerData->SetClippingRegion(region);
/*
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
fCurrentLayer->RebuildFullRegion(); fCurrentLayer->RebuildFullRegion();
if (!(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate()) if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull); myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull);
#else #else
if (!(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate()) if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame()); myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame());
#endif #endif
*/
break; break;
} }
case AS_LAYER_INVAL_RECT: case AS_LAYER_INVAL_RECT:
@@ -1061,13 +1068,17 @@ myRootLayer->Unlock();
BRect invalRect; BRect invalRect;
link.Read<BRect>(&invalRect); link.Read<BRect>(&invalRect);
BRect converted(fCurrentLayer->ConvertToTop(invalRect.LeftTop()),
fCurrentLayer->ConvertToTop(invalRect.RightBottom()));
BRegion invalidRegion(converted);
// invalidRegion.IntersectWith(&fCurrentLayer->fVisible);
myRootLayer->GoRedraw(fWinBorder, invalidRegion); if (myRootLayer) {
// myRootLayer->RequestDraw(invalidRegion, fWinBorder); BRect converted(fCurrentLayer->ConvertToTop(invalRect.LeftTop()),
fCurrentLayer->ConvertToTop(invalRect.RightBottom()));
BRegion invalidRegion(converted);
#ifdef NEW_CLIPPING
invalidRegion.IntersectWith(&fCurrentLayer->fVisible2);
#endif
myRootLayer->GoRedraw(fWinBorder, invalidRegion);
// myRootLayer->RequestDraw(invalidRegion, fWinBorder);
}
break; break;
} }
case AS_LAYER_INVAL_REGION: case AS_LAYER_INVAL_REGION:
@@ -1082,30 +1093,26 @@ myRootLayer->Unlock();
link.Read<int32>(&noOfRects); link.Read<int32>(&noOfRects);
for(int i = 0; i < noOfRects; i++) for (int i = 0; i < noOfRects; i++) {
{
link.Read<BRect>(&rect); link.Read<BRect>(&rect);
invalReg.Include(rect); invalReg.Include(rect);
} }
myRootLayer->GoRedraw(fCurrentLayer, invalReg); if (myRootLayer)
myRootLayer->GoRedraw(fCurrentLayer, invalReg);
break; break;
} }
case AS_BEGIN_UPDATE: case AS_BEGIN_UPDATE:
{ {
DTRACE(("ServerWindowo %s: AS_BEGIN_UPDATE\n", Title())); DTRACE(("ServerWindowo %s: AS_BEGIN_UPDATE\n", Title()));
fWinBorder->GetRootLayer()->Lock();
fWinBorder->UpdateStart(); fWinBorder->UpdateStart();
fWinBorder->GetRootLayer()->Unlock();
break; break;
} }
case AS_END_UPDATE: case AS_END_UPDATE:
{ {
DTRACE(("ServerWindowo %s: AS_END_UPDATE\n", Title())); DTRACE(("ServerWindowo %s: AS_END_UPDATE\n", Title()));
fWinBorder->GetRootLayer()->Lock();
fWinBorder->UpdateEnd(); fWinBorder->UpdateEnd();
fWinBorder->GetRootLayer()->Unlock();
break; break;
} }
@@ -1160,7 +1167,6 @@ myRootLayer->Unlock();
#endif #endif
case AS_WINDOW_TITLE: case AS_WINDOW_TITLE:
{ {
// TODO: Implement AS_WINDOW_TITLE
char* newTitle; char* newTitle;
if (link.ReadString(&newTitle) == B_OK) { if (link.ReadString(&newTitle) == B_OK) {
@@ -1169,6 +1175,10 @@ myRootLayer->Unlock();
free(newTitle); free(newTitle);
} }
char* title;
link.ReadString(&title);
fWinBorder->SetName(title);
free(title);
break; break;
} }
@@ -1243,7 +1253,9 @@ myRootLayer->Unlock();
STRACE(("ServerWindow %s: Message AS_SET_FEEL\n", Title())); STRACE(("ServerWindow %s: Message AS_SET_FEEL\n", Title()));
int32 newFeel; int32 newFeel;
link.Read<int32>(&newFeel); link.Read<int32>(&newFeel);
myRootLayer->GoChangeWinBorderFeel(fWinBorder, newFeel);
if (myRootLayer)
myRootLayer->GoChangeWinBorderFeel(fWinBorder, newFeel);
break; break;
} }
case AS_SET_ALIGNMENT: case AS_SET_ALIGNMENT:
@@ -1511,16 +1523,15 @@ myRootLayer->Unlock();
break; break;
} }
myRootLayer->Unlock(); if (myRootLayer)
myRootLayer->Unlock();
} }
// -------------------- Graphics messages ---------------------------------- // -------------------- Graphics messages ----------------------------------
inline
void void
ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link) ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
{ {
fWinBorder->GetRootLayer()->Lock();
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
BRegion rreg(fCurrentLayer->fVisible); BRegion rreg(fCurrentLayer->fVisible);
#else #else
@@ -1530,10 +1541,12 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
if (fWinBorder->InUpdate()) if (fWinBorder->InUpdate())
rreg.IntersectWith(&fWinBorder->RegionToBeUpdated()); rreg.IntersectWith(&fWinBorder->RegionToBeUpdated());
gDesktop->GetDisplayDriver()->ConstrainClippingRegion(&rreg); DisplayDriver* driver = fWinBorder->GetDisplayDriver();
driver->ConstrainClippingRegion(&rreg);
// rgb_color rrr = fCurrentLayer->fLayerData->viewcolor.GetColor32(); // rgb_color rrr = fCurrentLayer->fLayerData->viewcolor.GetColor32();
// RGBColor c(rand()%255,rand()%255,rand()%255); // RGBColor c(rand()%255,rand()%255,rand()%255);
// gDesktop->GetDisplayDriver()->FillRect(BRect(0,0,639,479), c); // driver->FillRect(BRect(0,0,639,479), c);
switch (code) { switch (code) {
case AS_STROKE_LINE: case AS_STROKE_LINE:
@@ -1548,11 +1561,12 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<float>(&y2); link.Read<float>(&y2);
if (fCurrentLayer && fCurrentLayer->fLayerData) { if (fCurrentLayer && fCurrentLayer->fLayerData) {
BPoint p1(x1,y1); BPoint p1(x1,y1);
BPoint p2(x2,y2); BPoint p2(x2,y2);
gDesktop->GetDisplayDriver()->StrokeLine(fCurrentLayer->ConvertToTop(p1), driver->StrokeLine(fCurrentLayer->ConvertToTop(p1),
fCurrentLayer->ConvertToTop(p2), fCurrentLayer->ConvertToTop(p2),
fCurrentLayer->fLayerData); fCurrentLayer->fLayerData);
// We update the pen here because many DisplayDriver calls which do not update the // We update the pen here because many DisplayDriver calls which do not update the
// pen position actually call StrokeLine // pen position actually call StrokeLine
@@ -1572,7 +1586,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<BRect>(&rect); link.Read<BRect>(&rect);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->InvertRect(fCurrentLayer->ConvertToTop(rect)); driver->InvertRect(fCurrentLayer->ConvertToTop(rect));
break; break;
} }
case AS_STROKE_RECT: case AS_STROKE_RECT:
@@ -1587,7 +1601,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
BRect rect(left,top,right,bottom); BRect rect(left,top,right,bottom);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->StrokeRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData); driver->StrokeRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
break; break;
} }
case AS_FILL_RECT: case AS_FILL_RECT:
@@ -1597,7 +1611,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
BRect rect; BRect rect;
link.Read<BRect>(&rect); link.Read<BRect>(&rect);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->FillRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData); driver->FillRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
break; break;
} }
case AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT: case AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT:
@@ -1615,7 +1629,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
BRect dst = src.OffsetToCopy(point); BRect dst = src.OffsetToCopy(point);
dst = fCurrentLayer->ConvertToTop(dst); dst = fCurrentLayer->ConvertToTop(dst);
fCurrentLayer->GetDisplayDriver()->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData); driver->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData);
} }
// TODO: Adi -- shouldn't AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT sync with the client? // TODO: Adi -- shouldn't AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT sync with the client?
@@ -1636,7 +1650,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
BRect dst = src.OffsetToCopy(point); BRect dst = src.OffsetToCopy(point);
dst = fCurrentLayer->ConvertToTop(dst); dst = fCurrentLayer->ConvertToTop(dst);
fCurrentLayer->GetDisplayDriver()->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData); driver->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData);
} }
break; break;
} }
@@ -1654,7 +1668,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
if (sbmp) { if (sbmp) {
dstRect = fCurrentLayer->ConvertToTop(dstRect); dstRect = fCurrentLayer->ConvertToTop(dstRect);
fCurrentLayer->GetDisplayDriver()->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData); driver->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData);
} }
// TODO: Adi -- shouldn't AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT sync with the client? // TODO: Adi -- shouldn't AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT sync with the client?
@@ -1674,7 +1688,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
if (sbmp) { if (sbmp) {
dstRect = fCurrentLayer->ConvertToTop(dstRect); dstRect = fCurrentLayer->ConvertToTop(dstRect);
fCurrentLayer->GetDisplayDriver()->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData); driver->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData);
} }
break; break;
} }
@@ -1689,7 +1703,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<float>(&angle); link.Read<float>(&angle);
link.Read<float>(&span); link.Read<float>(&span);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->StrokeArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData); driver->StrokeArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData);
break; break;
} }
case AS_FILL_ARC: case AS_FILL_ARC:
@@ -1703,7 +1717,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<float>(&angle); link.Read<float>(&angle);
link.Read<float>(&span); link.Read<float>(&span);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->FillArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData); driver->FillArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData);
break; break;
} }
case AS_STROKE_BEZIER: case AS_STROKE_BEZIER:
@@ -1722,7 +1736,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
for (i=0; i<4; i++) for (i=0; i<4; i++)
pts[i]=fCurrentLayer->ConvertToTop(pts[i]); pts[i]=fCurrentLayer->ConvertToTop(pts[i]);
gDesktop->GetDisplayDriver()->StrokeBezier(pts, fCurrentLayer->fLayerData); driver->StrokeBezier(pts, fCurrentLayer->fLayerData);
} }
delete [] pts; delete [] pts;
break; break;
@@ -1743,7 +1757,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
for (i=0; i<4; i++) for (i=0; i<4; i++)
pts[i]=fCurrentLayer->ConvertToTop(pts[i]); pts[i]=fCurrentLayer->ConvertToTop(pts[i]);
gDesktop->GetDisplayDriver()->FillBezier(pts, fCurrentLayer->fLayerData); driver->FillBezier(pts, fCurrentLayer->fLayerData);
} }
delete [] pts; delete [] pts;
break; break;
@@ -1755,7 +1769,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
BRect rect; BRect rect;
link.Read<BRect>(&rect); link.Read<BRect>(&rect);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->StrokeEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData); driver->StrokeEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
break; break;
} }
case AS_FILL_ELLIPSE: case AS_FILL_ELLIPSE:
@@ -1765,7 +1779,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
BRect rect; BRect rect;
link.Read<BRect>(&rect); link.Read<BRect>(&rect);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->FillEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData); driver->FillEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
break; break;
} }
case AS_STROKE_ROUNDRECT: case AS_STROKE_ROUNDRECT:
@@ -1779,7 +1793,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<float>(&yrad); link.Read<float>(&yrad);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->StrokeRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData); driver->StrokeRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData);
break; break;
} }
case AS_FILL_ROUNDRECT: case AS_FILL_ROUNDRECT:
@@ -1793,7 +1807,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<float>(&yrad); link.Read<float>(&yrad);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->FillRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData); driver->FillRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData);
break; break;
} }
case AS_STROKE_TRIANGLE: case AS_STROKE_TRIANGLE:
@@ -1812,7 +1826,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
for (int i = 0;i < 3; i++) for (int i = 0;i < 3; i++)
pts[i] = fCurrentLayer->ConvertToTop(pts[i]); pts[i] = fCurrentLayer->ConvertToTop(pts[i]);
gDesktop->GetDisplayDriver()->StrokeTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData); driver->StrokeTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
} }
break; break;
} }
@@ -1832,7 +1846,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
pts[i] = fCurrentLayer->ConvertToTop(pts[i]); pts[i] = fCurrentLayer->ConvertToTop(pts[i]);
gDesktop->GetDisplayDriver()->FillTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData); driver->FillTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
} }
break; break;
} }
@@ -1857,7 +1871,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
for (int32 i = 0; i < pointcount; i++) for (int32 i = 0; i < pointcount; i++)
pointlist[i] = fCurrentLayer->ConvertToTop(pointlist[i]); pointlist[i] = fCurrentLayer->ConvertToTop(pointlist[i]);
gDesktop->GetDisplayDriver()->StrokePolygon(pointlist,pointcount,polyframe, driver->StrokePolygon(pointlist,pointcount,polyframe,
fCurrentLayer->fLayerData,isclosed); fCurrentLayer->fLayerData,isclosed);
delete [] pointlist; delete [] pointlist;
@@ -1881,7 +1895,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
for (int32 i = 0; i < pointcount; i++) for (int32 i = 0; i < pointcount; i++)
pointlist[i] = fCurrentLayer->ConvertToTop(pointlist[i]); pointlist[i] = fCurrentLayer->ConvertToTop(pointlist[i]);
gDesktop->GetDisplayDriver()->FillPolygon(pointlist,pointcount,polyframe, fCurrentLayer->fLayerData); driver->FillPolygon(pointlist,pointcount,polyframe, fCurrentLayer->fLayerData);
delete [] pointlist; delete [] pointlist;
break; break;
@@ -1909,7 +1923,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
for (int32 i = 0; i < ptcount; i++) for (int32 i = 0; i < ptcount; i++)
ptlist[i] = fCurrentLayer->ConvertToTop(ptlist[i]); ptlist[i] = fCurrentLayer->ConvertToTop(ptlist[i]);
gDesktop->GetDisplayDriver()->StrokeShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData); driver->StrokeShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData);
delete[] oplist; delete[] oplist;
delete[] ptlist; delete[] ptlist;
break; break;
@@ -1937,7 +1951,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
for (int32 i = 0; i < ptcount; i++) for (int32 i = 0; i < ptcount; i++)
ptlist[i] = fCurrentLayer->ConvertToTop(ptlist[i]); ptlist[i] = fCurrentLayer->ConvertToTop(ptlist[i]);
gDesktop->GetDisplayDriver()->FillShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData); driver->FillShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData);
delete[] oplist; delete[] oplist;
delete[] ptlist; delete[] ptlist;
@@ -1959,10 +1973,11 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
// Between the client-side conversion to BRects from clipping_rects to the overhead // Between the client-side conversion to BRects from clipping_rects to the overhead
// in repeatedly calling FillRect(), this is definitely in need of optimization. At // in repeatedly calling FillRect(), this is definitely in need of optimization. At
// least it works for now. :) // least it works for now. :)
BRegion region;
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
gDesktop->GetDisplayDriver()->FillRect(fCurrentLayer->ConvertToTop(rects[i]), region.Include(fCurrentLayer->ConvertToTop(rects[i]));
fCurrentLayer->fLayerData);
} }
driver->FillRegion(region, fCurrentLayer->fLayerData);
delete[] rects; delete[] rects;
@@ -1996,7 +2011,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
index->pt1 = fCurrentLayer->ConvertToTop(index->pt1); index->pt1 = fCurrentLayer->ConvertToTop(index->pt1);
index->pt2 = fCurrentLayer->ConvertToTop(index->pt2); index->pt2 = fCurrentLayer->ConvertToTop(index->pt2);
} }
gDesktop->GetDisplayDriver()->StrokeLineArray(linecount,linedata,fCurrentLayer->fLayerData); driver->StrokeLineArray(linecount,linedata,fCurrentLayer->fLayerData);
} }
break; break;
} }
@@ -2014,13 +2029,22 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
link.ReadString(&string); link.ReadString(&string);
if (fCurrentLayer && fCurrentLayer->fLayerData) if (fCurrentLayer && fCurrentLayer->fLayerData)
gDesktop->GetDisplayDriver()->DrawString(string, length, driver->DrawString(string, length,
fCurrentLayer->ConvertToTop(location), fCurrentLayer->ConvertToTop(location),
fCurrentLayer->fLayerData); fCurrentLayer->fLayerData);
free(string); free(string);
break; break;
} }
case AS_LAYER_BEGIN_PICTURE:
CRITICAL("AS_LAYER_BEGIN_PICTURE not implemented\n");
break;
case AS_LAYER_APPEND_TO_PICTURE:
CRITICAL("AS_LAYER_APPEND_TO_PICTURE not implemented\n");
break;
case AS_LAYER_END_PICTURE:
CRITICAL("AS_LAYER_END_PICTURE not implemented\n");
break;
default: default:
printf("ServerWindow %s received unexpected code - message offset %ld\n", printf("ServerWindow %s received unexpected code - message offset %ld\n",
@@ -2034,8 +2058,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
break; break;
} }
gDesktop->GetDisplayDriver()->ConstrainClippingRegion(NULL); driver->ConstrainClippingRegion(NULL);
fWinBorder->GetRootLayer()->Unlock();
} }
/*! /*!
@@ -2123,6 +2146,72 @@ ServerWindow::_MessageLooper()
} }
} }
/*
void
ServerWindow::_CopyBits(RootLayer* rootLayer, Layer* layer,
BRect& src, BRect& dst,
int32 xOffset, int32 yOffset) const
{
// NOTE: The correct behaviour is this:
// * The region that is copied is the
// src rectangle, no matter if it fits
// into the dst rectangle. It is copied
// by the offset dst.LeftTop() - src.LeftTop()
// * The dst rectangle is used for invalidation:
// Any area in the dst rectangle that could
// not be copied from src (because either the
// src rectangle was not big enough, or because there
// were parts cut off by the current layer clipping),
// are triggering BView::Draw() to be called
// and for these parts only.
#ifndef NEW_CLIPPING
// the region that is going to be copied
BRegion copyRegion(src);
// apply the current clipping of the layer
copyRegion.IntersectWith(&layer->fVisible);
// offset the region to the destination
// and apply the current clipping there as well
copyRegion.OffsetBy(xOffset, yOffset);
copyRegion.IntersectWith(&layer->fVisible);
// the region at the destination that needs invalidation
BRegion invalidRegion(dst);
// exclude the region drawn by the copy operation
invalidRegion.Exclude(&copyRegion);
// apply the current clipping as well
invalidRegion.IntersectWith(&layer->fVisible);
// move the region back for the actual operation
copyRegion.OffsetBy(-xOffset, -yOffset);
layer->GetDisplayDriver()->CopyRegion(&copyRegion, xOffset, yOffset);
// trigger the redraw
if (rootLayer) {
// the following code solves a "concurrency" problem:
// since the scrolling might happen more often
// than redrawing, we need to keep track of the region
// pending for redraw that might fall into the area
// that is scrolled.
BRegion scrolledInvalid(fWinBorder->CulmulatedUpdateRegion());
scrolledInvalid.IntersectWith(&layer->fVisible);
if (scrolledInvalid.Frame().IsValid()) {
//printf("the layer has pending updates that will be scrolled\n");
scrolledInvalid.OffsetBy(xOffset, yOffset);
invalidRegion.Include(&scrolledInvalid);
}
rootLayer->GoRedraw(fWinBorder, invalidRegion);
}
#endif
}*/
void void
ServerWindow::SendMessageToClient(const BMessage* msg, int32 target, bool usePreferred) const ServerWindow::SendMessageToClient(const BMessage* msg, int32 target, bool usePreferred) const
{ {
@@ -2140,6 +2229,16 @@ ServerWindow::SendMessageToClient(const BMessage* msg, int32 target, bool usePre
delete[] buffer; delete[] buffer;
} }
// MakeWinBorder
WinBorder*
ServerWindow::MakeWinBorder(BRect frame, const char* name,
uint32 look, uint32 feel, uint32 flags,
uint32 workspace)
{
// The non-offscreen ServerWindow uses the DisplayDriver instance from the desktop.
return new(nothrow) WinBorder(frame, name, look, feel, flags,
workspace, this, gDesktop->GetDisplayDriver());
}
status_t status_t
ServerWindow::PictureToRegion(ServerPicture *picture, BRegion &region, ServerWindow::PictureToRegion(ServerPicture *picture, BRegion &region,
+11 -4
View File
@@ -55,11 +55,12 @@ class ServerWindow : public BLocker {
public: public:
ServerWindow(const char *title, ServerApp *app, ServerWindow(const char *title, ServerApp *app,
port_id clientPort, port_id looperPort, port_id clientPort, port_id looperPort,
int32 handlerID, BRect frame, uint32 look, int32 handlerID);
uint32 feel, uint32 flags, uint32 workspace);
virtual ~ServerWindow(); virtual ~ServerWindow();
status_t InitCheck(); status_t Init(BRect frame, uint32 look,
uint32 feel, uint32 flags,
uint32 workspace);
bool Run(); bool Run();
void Quit(); void Quit();
@@ -77,9 +78,15 @@ public:
const color_space cspace); const color_space cspace);
// util methods. // util methods.
void SendMessageToClient(const BMessage* msg, virtual void SendMessageToClient(const BMessage* msg,
int32 target = B_NULL_TOKEN, int32 target = B_NULL_TOKEN,
bool usePreferred = false) const; bool usePreferred = false) const;
virtual WinBorder* MakeWinBorder(BRect frame,
const char* name,
uint32 look, uint32 feel,
uint32 flags, uint32 workspace);
// TODO: Ouch, that's not exactly a nice name // TODO: Ouch, that's not exactly a nice name
inline BMessage &ClientViewsWithInvalidCoords() inline BMessage &ClientViewsWithInvalidCoords()
+4 -1
View File
@@ -25,6 +25,8 @@
// Description: Methods to initialize and get the system color_map. // Description: Methods to initialize and get the system color_map.
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#include <stdio.h>
#include <SystemPalette.h> #include <SystemPalette.h>
const static rgb_color kSystemPalette[] = { const static rgb_color kSystemPalette[] = {
@@ -155,7 +157,7 @@ color_distance(uint8 red1, uint8 green1, uint8 blue1,
} }
static uint8 static inline uint8
FindClosestColor(const rgb_color &color, const rgb_color *palette) FindClosestColor(const rgb_color &color, const rgb_color *palette)
{ {
uint8 closestIndex = 0; uint8 closestIndex = 0;
@@ -221,6 +223,7 @@ FillColorMap(const rgb_color *palette, color_map *map)
void void
InitializeColorMap() InitializeColorMap()
{ {
printf("InitializeColorMap()\n");
FillColorMap(kSystemPalette, &sColorMap); FillColorMap(kSystemPalette, &sColorMap);
} }
+46 -7
View File
@@ -129,8 +129,6 @@ WinBorder::WinBorder(const BRect &frame,
RebuildFullRegion(); RebuildFullRegion();
#endif #endif
gDesktop->AddWinBorder(this);
STRACE(("WinBorder %s:\n", GetName())); STRACE(("WinBorder %s:\n", GetName()));
STRACE(("\tFrame: (%.1f, %.1f, %.1f, %.1f)\n", r.left, r.top, r.right, r.bottom)); STRACE(("\tFrame: (%.1f, %.1f, %.1f, %.1f)\n", r.left, r.top, r.right, r.bottom));
STRACE(("\tWindow %s\n", window ? window->Title() : "NULL")); STRACE(("\tWindow %s\n", window ? window->Title() : "NULL"));
@@ -141,8 +139,6 @@ WinBorder::~WinBorder()
{ {
STRACE(("WinBorder(%s)::~WinBorder()\n",GetName())); STRACE(("WinBorder(%s)::~WinBorder()\n",GetName()));
gDesktop->RemoveWinBorder(this);
delete fTopLayer; delete fTopLayer;
delete fDecorator; delete fDecorator;
} }
@@ -274,7 +270,7 @@ WinBorder::_ResizeBy(float x, float y)
if (x == 0.0 && y == 0.0) if (x == 0.0 && y == 0.0)
return false; return false;
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
if (fDecorator) if (fDecorator)
fDecorator->ResizeBy(x, y); fDecorator->ResizeBy(x, y);
@@ -296,6 +292,34 @@ WinBorder::_ResizeBy(float x, float y)
return true; return true;
} }
// SetName
void
WinBorder::SetName(const char* name)
{
Layer::SetName(name);
// rebuild the clipping for the title area
// and redraw it.
// TODO: Adi, please have a look at this,
// it doesn't work yet.
if (fDecorator) {
// before the change
BRegion invalid(fDecorator->GetTabRect());
fDecorator->SetTitle(name);
// after the change
invalid.Include(fDecorator->GetTabRect());
#ifndef NEW_CLIPPING
RebuildFullRegion();
fRootLayer->GoRedraw(this, invalid);
#else
// TODO: ...
#endif
}
}
// UpdateStart // UpdateStart
void void
@@ -375,7 +399,9 @@ WinBorder::SetSizeLimits(float minWidth, float maxWidth,
// On R5, Windows don't automatically resize, but since // On R5, Windows don't automatically resize, but since
// BWindow::ResizeTo() even honors the limits, I would guess // BWindow::ResizeTo() even honors the limits, I would guess
// this is a bug that we don't have to adopt // this is a bug that we don't have to adopt.
// Note that most current apps will do unnecessary resizing
// after having set the limits, but the overhead is neglible.
float minWidthDiff = fMinWidth - fFrame.Width(); float minWidthDiff = fMinWidth - fFrame.Width();
float minHeightDiff = fMinHeight - fFrame.Height(); float minHeightDiff = fMinHeight - fFrame.Height();
@@ -394,7 +420,6 @@ WinBorder::SetSizeLimits(float minWidth, float maxWidth,
else if (maxHeightDiff < 0.0) // we're currently larger than maxHeight else if (maxHeightDiff < 0.0) // we're currently larger than maxHeight
yDiff = maxHeightDiff; yDiff = maxHeightDiff;
// Layer::ResizeBy(xDiff, yDiff);
ResizeBy(xDiff, yDiff); ResizeBy(xDiff, yDiff);
} }
@@ -776,3 +801,17 @@ void WinBorder::get_user_regions(BRegion &reg)
reg.Include(&fDecRegion); reg.Include(&fDecRegion);
} }
#endif #endif
// SetTopLayer
void
WinBorder::SetTopLayer(Layer* layer)
{
if (layer) {
fTopLayer = layer;
fTopLayer->SetAsTopLayer(true);
// connect decorator and top layer. (?)
AddChild(fTopLayer, NULL);
}
}
+13 -1
View File
@@ -66,6 +66,12 @@ class WinBorder : public Layer {
virtual void ScrollBy(float x, float y) virtual void ScrollBy(float x, float y)
{ // not allowed { // not allowed
} }
virtual void SetName(const char* name);
virtual bool IsOffscreenWindow() const
{ return false; }
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
virtual void RebuildFullRegion(); virtual void RebuildFullRegion();
#endif #endif
@@ -76,6 +82,8 @@ class WinBorder : public Layer {
{ return fInUpdate; } { return fInUpdate; }
inline const BRegion& RegionToBeUpdated() const inline const BRegion& RegionToBeUpdated() const
{ return fInUpdateRegion; } { return fInUpdateRegion; }
inline const BRegion& CulmulatedUpdateRegion() const
{ return fCumulativeRegion; }
void SetSizeLimits(float minWidth, void SetSizeLimits(float minWidth,
float maxWidth, float maxWidth,
@@ -131,9 +139,13 @@ class WinBorder : public Layer {
#endif #endif
public:
virtual void SetTopLayer(Layer* layer);
inline Layer* TopLayer() const
{ return fTopLayer; }
protected: protected:
friend class Layer; friend class Layer;
friend class ServerWindow;
friend class RootLayer; friend class RootLayer;
click_type _ActionFor(const PointerEvent& evt) const; click_type _ActionFor(const PointerEvent& evt) const;
+10 -6
View File
@@ -1,11 +1,15 @@
// BitmapBuffer.h // BitmapBuffer.h
#include <Bitmap.h> #include "ServerBitmap.h"
#include "BitmapBuffer.h" #include "BitmapBuffer.h"
// TODO: It should be more or less guaranteed that this object
// is not used if InitCheck() returns an error, so the checks
// in all thos functions should probably be removed...
// constructor // constructor
BitmapBuffer::BitmapBuffer(BBitmap* bitmap) BitmapBuffer::BitmapBuffer(ServerBitmap* bitmap)
: fBitmap(bitmap) : fBitmap(bitmap)
{ {
} }
@@ -13,7 +17,7 @@ BitmapBuffer::BitmapBuffer(BBitmap* bitmap)
// destructor // destructor
BitmapBuffer::~BitmapBuffer() BitmapBuffer::~BitmapBuffer()
{ {
delete fBitmap; // We don't own the ServerBitmap
} }
// InitCheck // InitCheck
@@ -22,7 +26,7 @@ BitmapBuffer::InitCheck() const
{ {
status_t ret = B_NO_INIT; status_t ret = B_NO_INIT;
if (fBitmap) if (fBitmap)
ret = fBitmap->InitCheck(); ret = fBitmap->IsValid() ? B_OK : B_ERROR;
return ret; return ret;
} }
@@ -58,7 +62,7 @@ uint32
BitmapBuffer::Width() const BitmapBuffer::Width() const
{ {
if (InitCheck() >= B_OK) if (InitCheck() >= B_OK)
return fBitmap->Bounds().IntegerWidth() + 1; return fBitmap->Width();
return 0; return 0;
} }
@@ -67,7 +71,7 @@ uint32
BitmapBuffer::Height() const BitmapBuffer::Height() const
{ {
if (InitCheck() >= B_OK) if (InitCheck() >= B_OK)
return fBitmap->Bounds().IntegerHeight() + 1; return fBitmap->Height();
return 0; return 0;
} }
+4 -4
View File
@@ -5,11 +5,11 @@
#include "RenderingBuffer.h" #include "RenderingBuffer.h"
class BBitmap; class ServerBitmap;
class BitmapBuffer : public RenderingBuffer { class BitmapBuffer : public RenderingBuffer {
public: public:
BitmapBuffer(BBitmap* bitmap); BitmapBuffer(ServerBitmap* bitmap);
virtual ~BitmapBuffer(); virtual ~BitmapBuffer();
virtual status_t InitCheck() const; virtual status_t InitCheck() const;
@@ -21,11 +21,11 @@ class BitmapBuffer : public RenderingBuffer {
virtual uint32 Height() const; virtual uint32 Height() const;
// BitmapBuffer // BitmapBuffer
const BBitmap* Bitmap() const const ServerBitmap* Bitmap() const
{ return fBitmap; } { return fBitmap; }
private: private:
BBitmap* fBitmap; ServerBitmap* fBitmap;
}; };
#endif // BITMAP_BUFFER_H #endif // BITMAP_BUFFER_H
@@ -0,0 +1,201 @@
//------------------------------------------------------------------------------
//
// Copyright 2002-2005, Haiku, Inc. All rights reserved.
// Distributed under the terms of the MIT License.
//
//
// File Name: BitmapHWInterface.cpp
// Authors: Michael Lotz <[email protected]>
// DarkWyrm <[email protected]>
// Stephan Aßmus <[email protected]>
// Description: Accelerant based HWInterface implementation
//
//------------------------------------------------------------------------------
#include <new>
#include <stdio.h>
#include <string.h>
#include <Cursor.h>
#include "Bitmap.h"
#include "BitmapBuffer.h"
#include "BBitmapBuffer.h"
#include "BitmapHWInterface.h"
// constructor
BitmapHWInterface::BitmapHWInterface(ServerBitmap* bitmap)
: HWInterface(),
fBackBuffer(NULL),
fFrontBuffer(new(nothrow) BitmapBuffer(bitmap))
{
}
// destructor
BitmapHWInterface::~BitmapHWInterface()
{
delete fBackBuffer;
delete fFrontBuffer;
}
// Initialize
status_t
BitmapHWInterface::Initialize()
{
status_t ret = HWInterface::Initialize();
if (ret < B_OK)
return ret;
ret = fFrontBuffer->InitCheck();
if (ret < B_OK)
return ret;
// TODO: Remove once unnecessary...
// fall back to double buffered mode until Painter knows how
// to draw onto non 32-bit surfaces...
if (fFrontBuffer->ColorSpace() != B_RGB32 &&
fFrontBuffer->ColorSpace() != B_RGBA32) {
BBitmap* backBitmap = new BBitmap(fFrontBuffer->Bounds(),
B_BITMAP_NO_SERVER_LINK,
B_RGBA32);
fBackBuffer = new BBitmapBuffer(backBitmap);
ret = fBackBuffer->InitCheck();
if (ret < B_OK) {
delete fBackBuffer;
fBackBuffer = NULL;
} else {
// import the current contents of the bitmap
// into the back bitmap
backBitmap->ImportBits(fFrontBuffer->Bits(),
fFrontBuffer->BitsLength(),
fFrontBuffer->BytesPerRow(),
0,
fFrontBuffer->ColorSpace());
}
}
return ret;
}
// Shutdown
status_t
BitmapHWInterface::Shutdown()
{
return B_OK;
}
// SetMode
status_t
BitmapHWInterface::SetMode(const display_mode &mode)
{
return B_UNSUPPORTED;
}
// GetMode
void
BitmapHWInterface::GetMode(display_mode *mode)
{
if (mode) {
memset(mode, 0, sizeof(display_mode));
}
}
// GetDeviceInfo
status_t
BitmapHWInterface::GetDeviceInfo(accelerant_device_info *info)
{
return B_UNSUPPORTED;
}
// GetModeList
status_t
BitmapHWInterface::GetModeList(display_mode** modes, uint32 *count)
{
return B_UNSUPPORTED;
}
// GetPixelClockLimits
status_t
BitmapHWInterface::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
{
return B_UNSUPPORTED;
}
// GetPixelClockLimits
status_t
BitmapHWInterface::GetTimingConstraints(display_timing_constraints *dtc)
{
return B_UNSUPPORTED;
}
// ProposeMode
status_t
BitmapHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high)
{
return B_UNSUPPORTED;
}
// RetraceSemaphore
sem_id
BitmapHWInterface::RetraceSemaphore()
{
return B_ERROR;
}
// WaitForRetrace
status_t
BitmapHWInterface::WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT)
{
return B_UNSUPPORTED;
}
// SetDPMSMode
status_t
BitmapHWInterface::SetDPMSMode(const uint32 &state)
{
return B_UNSUPPORTED;
}
// DPMSMode
uint32
BitmapHWInterface::DPMSMode()
{
return 0;
}
// DPMSCapabilities
uint32
BitmapHWInterface::DPMSCapabilities()
{
return 0;
}
// FrontBuffer
RenderingBuffer *
BitmapHWInterface::FrontBuffer() const
{
return fFrontBuffer;
}
// BackBuffer
RenderingBuffer *
BitmapHWInterface::BackBuffer() const
{
return fBackBuffer;
}
// IsDoubleBuffered
bool
BitmapHWInterface::IsDoubleBuffered() const
{
// overwrite double buffered preference
if (fFrontBuffer)
return fBackBuffer != NULL;
return HWInterface::IsDoubleBuffered();
}
@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
// Copyright 2005, Haiku, Inc. All rights reserved.
// Distributed under the terms of the MIT License.
//
// Author: Stephan Aßmus, <[email protected]>
//------------------------------------------------------------------------------
#ifndef BITMAP_HW_INTERFACE_H
#define BITMAP_HW_INTERFACE_H
#include "HWInterface.h"
class BitmapBuffer;
class MallocBuffer;
class ServerBitmap;
class BBitmapBuffer;
class BitmapHWInterface : public HWInterface {
public:
BitmapHWInterface(ServerBitmap* bitmap);
virtual ~BitmapHWInterface();
virtual status_t Initialize();
virtual status_t Shutdown();
// overwrite all the meaningless functions with empty code
virtual status_t SetMode(const display_mode &mode);
virtual void GetMode(display_mode *mode);
virtual status_t GetDeviceInfo(accelerant_device_info *info);
virtual status_t GetModeList(display_mode **mode_list,
uint32 *count);
virtual status_t GetPixelClockLimits(display_mode *mode,
uint32 *low,
uint32 *high);
virtual status_t GetTimingConstraints(display_timing_constraints *dtc);
virtual status_t ProposeMode(display_mode *candidate,
const display_mode *low,
const display_mode *high);
virtual sem_id RetraceSemaphore();
virtual status_t WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT);
virtual status_t SetDPMSMode(const uint32 &state);
virtual uint32 DPMSMode();
virtual uint32 DPMSCapabilities();
// frame buffer access
virtual RenderingBuffer* FrontBuffer() const;
virtual RenderingBuffer* BackBuffer() const;
virtual bool IsDoubleBuffered() const;
private:
BBitmapBuffer* fBackBuffer;
BitmapBuffer* fFrontBuffer;
};
#endif // BITMAP_HW_INTERFACE_H
+354 -261
View File
@@ -19,11 +19,36 @@
#include "DisplayDriverPainter.h" #include "DisplayDriverPainter.h"
// make_rect_valid
static inline void
make_rect_valid(BRect& rect)
{
if (rect.left > rect.right) {
float temp = rect.left;
rect.left = rect.right;
rect.right = temp;
}
if (rect.top > rect.bottom) {
float temp = rect.top;
rect.top = rect.bottom;
rect.bottom = temp;
}
}
// extend_by_stroke_width
static inline void
extend_by_stroke_width(BRect& rect, const DrawData* context)
{
// "- 1.0" because if stroke width == 1, we don't need to extend
float inset = -ceilf(context->PenSize() / 2.0 - 1.0);
rect.InsetBy(inset, inset);
}
// constructor // constructor
DisplayDriverPainter::DisplayDriverPainter(HWInterface* hwInterface) DisplayDriverPainter::DisplayDriverPainter(HWInterface* interface)
: DisplayDriver(), : DisplayDriver(),
fPainter(new Painter()), fPainter(new Painter()),
fGraphicsCard(hwInterface), fGraphicsCard(interface),
fAvailableHWAccleration(0) fAvailableHWAccleration(0)
{ {
} }
@@ -70,6 +95,13 @@ DisplayDriverPainter::Update()
} }
} }
// SetHWInterface
void
DisplayDriverPainter::SetHWInterface(HWInterface* interface)
{
fGraphicsCard = interface;
}
// ConstrainClippingRegion // ConstrainClippingRegion
void DisplayDriverPainter::ConstrainClippingRegion(BRegion *region) void DisplayDriverPainter::ConstrainClippingRegion(BRegion *region)
{ {
@@ -350,29 +382,26 @@ DisplayDriverPainter::CopyRegionList(BList* list, BList* pList,
// InvertRect // InvertRect
void void
DisplayDriverPainter::InvertRect(const BRect &r) DisplayDriverPainter::InvertRect(BRect r)
{ {
// NOTE: Write locking because we might use HW acceleration. // NOTE: Write locking because we might use HW acceleration.
// This needs to be investigated, I'm doing this because of // This needs to be investigated, I'm doing this because of
// gut feeling. // gut feeling.
if (WriteLock()) { if (WriteLock()) {
BRect vr(min_c(r.left, r.right), make_rect_valid(r);
min_c(r.top, r.bottom), r = fPainter->ClipRect(r);
max_c(r.left, r.right), if (r.IsValid()) {
max_c(r.top, r.bottom)); fGraphicsCard->HideSoftwareCursor(r);
vr = fPainter->ClipRect(vr);
if (vr.IsValid()) {
fGraphicsCard->HideSoftwareCursor(vr);
// try hardware optimized version first // try hardware optimized version first
if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) { if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) {
BRegion region(vr); BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion()); region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->InvertRegion(region); fGraphicsCard->InvertRegion(region);
} else { } else {
fPainter->InvertRect(vr); fPainter->InvertRect(r);
fGraphicsCard->Invalidate(vr); fGraphicsCard->Invalidate(r);
} }
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
@@ -390,13 +419,15 @@ DisplayDriverPainter::DrawBitmap(ServerBitmap *bitmap,
{ {
if (Lock()) { if (Lock()) {
BRect clipped = fPainter->ClipRect(dest); BRect clipped = fPainter->ClipRect(dest);
fGraphicsCard->HideSoftwareCursor(clipped); if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->SetDrawData(d);
BRect touched = fPainter->DrawBitmap(bitmap, source, dest); fPainter->SetDrawData(d);
fPainter->DrawBitmap(bitmap, source, dest);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->Invalidate(clipped);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -404,23 +435,27 @@ DisplayDriverPainter::DrawBitmap(ServerBitmap *bitmap,
// FillArc // FillArc
void void
DisplayDriverPainter::FillArc(const BRect &r, const float &angle, DisplayDriverPainter::FillArc(BRect r, const float &angle,
const float &span, const DrawData *d) const float &span, const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); make_rect_valid(r);
BRect clipped = fPainter->ClipRect(r);
fPainter->SetDrawData(d); if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
float xRadius = r.Width() / 2.0;
float yRadius = r.Width() / 2.0; fPainter->SetDrawData(d);
BPoint center(r.left + xRadius,
r.top + yRadius); float xRadius = r.Width() / 2.0;
float yRadius = r.Width() / 2.0;
BRect touched = fPainter->FillArc(center, xRadius, yRadius, angle, span); BPoint center(r.left + xRadius,
r.top + yRadius);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fPainter->FillArc(center, xRadius, yRadius, angle, span);
fGraphicsCard->Invalidate(clipped);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -446,22 +481,26 @@ DisplayDriverPainter::FillBezier(BPoint *pts, const DrawData *d)
// FillEllipse // FillEllipse
void void
DisplayDriverPainter::FillEllipse(const BRect &r, const DrawData *d) DisplayDriverPainter::FillEllipse(BRect r, const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); make_rect_valid(r);
BRect clipped = fPainter->ClipRect(r);
if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->SetDrawData(d); fPainter->SetDrawData(d);
float xRadius = r.Width() / 2.0; float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0; float yRadius = r.Height() / 2.0;
BPoint center(r.left + xRadius, BPoint center(r.left + xRadius,
r.top + yRadius); r.top + yRadius);
BRect touched = fPainter->FillEllipse(center, xRadius, yRadius); fPainter->FillEllipse(center, xRadius, yRadius);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(clipped);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -470,16 +509,20 @@ DisplayDriverPainter::FillEllipse(const BRect &r, const DrawData *d)
// FillPolygon // FillPolygon
void void
DisplayDriverPainter::FillPolygon(BPoint *ptlist, int32 numpts, DisplayDriverPainter::FillPolygon(BPoint *ptlist, int32 numpts,
const BRect &bounds, const DrawData *d) BRect bounds, const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); make_rect_valid(bounds);
BRect clipped = fPainter->ClipRect(bounds);
if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->SetDrawData(d); fPainter->SetDrawData(d);
BRect touched = fPainter->FillPolygon(ptlist, numpts); fPainter->FillPolygon(ptlist, numpts);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(clipped);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -487,29 +530,26 @@ DisplayDriverPainter::FillPolygon(BPoint *ptlist, int32 numpts,
// FillRect // FillRect
void void
DisplayDriverPainter::FillRect(const BRect& r, const RGBColor& color) DisplayDriverPainter::FillRect(BRect r, const RGBColor& color)
{ {
// NOTE: Write locking because we might use HW acceleration. // NOTE: Write locking because we might use HW acceleration.
// This needs to be investigated, I'm doing this because of // This needs to be investigated, I'm doing this because of
// gut feeling. // gut feeling.
if (WriteLock()) { if (WriteLock()) {
BRect vr(min_c(r.left, r.right), make_rect_valid(r);
min_c(r.top, r.bottom), r = fPainter->ClipRect(r);
max_c(r.left, r.right), if (r.IsValid()) {
max_c(r.top, r.bottom)); fGraphicsCard->HideSoftwareCursor(r);
vr = fPainter->ClipRect(vr);
if (vr.IsValid()) {
fGraphicsCard->HideSoftwareCursor(vr);
// try hardware optimized version first // try hardware optimized version first
if (fAvailableHWAccleration & HW_ACC_FILL_REGION) { if (fAvailableHWAccleration & HW_ACC_FILL_REGION) {
BRegion region(vr); BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion()); region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, color); fGraphicsCard->FillRegion(region, color);
} else { } else {
fPainter->FillRect(vr, color.GetColor32()); fPainter->FillRect(r, color.GetColor32());
fGraphicsCard->Invalidate(vr); fGraphicsCard->Invalidate(r);
} }
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
@@ -521,19 +561,16 @@ DisplayDriverPainter::FillRect(const BRect& r, const RGBColor& color)
// FillRect // FillRect
void void
DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d) DisplayDriverPainter::FillRect(BRect r, const DrawData *d)
{ {
// NOTE: Write locking because we might use HW acceleration. // NOTE: Write locking because we might use HW acceleration.
// This needs to be investigated, I'm doing this because of // This needs to be investigated, I'm doing this because of
// gut feeling. // gut feeling.
if (WriteLock()) { if (WriteLock()) {
BRect vr(min_c(r.left, r.right), make_rect_valid(r);
min_c(r.top, r.bottom), r = fPainter->ClipRect(r);
max_c(r.left, r.right), if (r.IsValid()) {
max_c(r.top, r.bottom)); fGraphicsCard->HideSoftwareCursor(r);
vr = fPainter->ClipRect(vr);
if (vr.IsValid()) {
fGraphicsCard->HideSoftwareCursor(vr);
bool doInSoftware = true; bool doInSoftware = true;
// try hardware optimized version first // try hardware optimized version first
@@ -542,12 +579,12 @@ DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d)
d->GetDrawingMode() == B_OP_OVER)) { d->GetDrawingMode() == B_OP_OVER)) {
if (d->GetPattern() == B_SOLID_HIGH) { if (d->GetPattern() == B_SOLID_HIGH) {
BRegion region(vr); BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion()); region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->HighColor()); fGraphicsCard->FillRegion(region, d->HighColor());
doInSoftware = false; doInSoftware = false;
} else if (d->GetPattern() == B_SOLID_LOW) { } else if (d->GetPattern() == B_SOLID_LOW) {
BRegion region(vr); BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion()); region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->LowColor()); fGraphicsCard->FillRegion(region, d->LowColor());
doInSoftware = false; doInSoftware = false;
@@ -556,9 +593,9 @@ DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d)
if (doInSoftware) { if (doInSoftware) {
fPainter->SetDrawData(d); fPainter->SetDrawData(d);
BRect touched = fPainter->FillRect(vr); fPainter->FillRect(r);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(r);
} }
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
@@ -576,57 +613,63 @@ DisplayDriverPainter::FillRegion(BRegion& r, const DrawData *d)
// This needs to be investigated, I'm doing this because of // This needs to be investigated, I'm doing this because of
// gut feeling. // gut feeling.
if (WriteLock()) { if (WriteLock()) {
BRect clipped = fPainter->ClipRect(r.Frame());
fGraphicsCard->HideSoftwareCursor(fPainter->ClipRect(r.Frame())); if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
bool doInSoftware = true;
// try hardware optimized version first bool doInSoftware = true;
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) && // try hardware optimized version first
(d->GetDrawingMode() == B_OP_COPY || if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) &&
d->GetDrawingMode() == B_OP_OVER)) { (d->GetDrawingMode() == B_OP_COPY ||
d->GetDrawingMode() == B_OP_OVER)) {
if (d->GetPattern() == B_SOLID_HIGH) {
fGraphicsCard->FillRegion(r, d->HighColor()); if (d->GetPattern() == B_SOLID_HIGH) {
doInSoftware = false; fGraphicsCard->FillRegion(r, d->HighColor());
} else if (d->GetPattern() == B_SOLID_LOW) { doInSoftware = false;
fGraphicsCard->FillRegion(r, d->LowColor()); } else if (d->GetPattern() == B_SOLID_LOW) {
doInSoftware = false; fGraphicsCard->FillRegion(r, d->LowColor());
doInSoftware = false;
}
} }
} if (doInSoftware) {
if (doInSoftware) {
fPainter->SetDrawData(d);
BRect touched = fPainter->FillRect(r.RectAt(0)); fPainter->SetDrawData(d);
int32 count = r.CountRects(); BRect touched = fPainter->FillRect(r.RectAt(0));
for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->FillRect(r.RectAt(i)); int32 count = r.CountRects();
for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->FillRect(r.RectAt(i));
}
fGraphicsCard->Invalidate(touched);
} }
fGraphicsCard->Invalidate(touched); fGraphicsCard->ShowSoftwareCursor();
} }
fGraphicsCard->ShowSoftwareCursor();
WriteUnlock(); WriteUnlock();
} }
} }
// FillRoundRect // FillRoundRect
void void
DisplayDriverPainter::FillRoundRect(const BRect &r, DisplayDriverPainter::FillRoundRect(BRect r,
const float &xrad, const float &yrad, const float &xrad, const float &yrad,
const DrawData *d) const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); make_rect_valid(r);
BRect clipped = fPainter->ClipRect(r);
fPainter->SetDrawData(d); if (clipped.IsValid()) {
BRect touched = fPainter->FillRoundRect(r, xrad, yrad); fGraphicsCard->HideSoftwareCursor(clipped);
fGraphicsCard->Invalidate(touched); fPainter->SetDrawData(d);
fGraphicsCard->ShowSoftwareCursor(); BRect touched = fPainter->FillRoundRect(r, xrad, yrad);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -649,17 +692,20 @@ printf("DisplayDriverPainter::FillShape() - what is this stuff that gets passed
// FillTriangle // FillTriangle
void void
DisplayDriverPainter::FillTriangle(BPoint *pts, const BRect &bounds, DisplayDriverPainter::FillTriangle(BPoint *pts, BRect bounds,
const DrawData *d) const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); bounds = fPainter->ClipRect(bounds);
if (bounds.IsValid()) {
fPainter->SetDrawData(d); fGraphicsCard->HideSoftwareCursor(bounds);
BRect touched = fPainter->FillTriangle(pts[0], pts[1], pts[2]);
fPainter->SetDrawData(d);
fGraphicsCard->Invalidate(touched); fPainter->FillTriangle(pts[0], pts[1], pts[2]);
fGraphicsCard->ShowSoftwareCursor();
fGraphicsCard->Invalidate(bounds);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -667,23 +713,27 @@ DisplayDriverPainter::FillTriangle(BPoint *pts, const BRect &bounds,
// StrokeArc // StrokeArc
void void
DisplayDriverPainter::StrokeArc(const BRect &r, const float &angle, DisplayDriverPainter::StrokeArc(BRect r, const float &angle,
const float &span, const DrawData *d) const float &span, const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); make_rect_valid(r);
BRect clipped = fPainter->ClipRect(r);
fPainter->SetDrawData(d); if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(r);
float xRadius = r.Width() / 2.0;
float yRadius = r.Width() / 2.0; fPainter->SetDrawData(d);
BPoint center(r.left + xRadius,
r.top + yRadius); float xRadius = r.Width() / 2.0;
float yRadius = r.Width() / 2.0;
BRect touched = fPainter->StrokeArc(center, xRadius, yRadius, angle, span); BPoint center(r.left + xRadius,
r.top + yRadius);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fPainter->StrokeArc(center, xRadius, yRadius, angle, span);
fGraphicsCard->Invalidate(clipped);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -708,22 +758,28 @@ DisplayDriverPainter::StrokeBezier(BPoint *pts, const DrawData *d)
// StrokeEllipse // StrokeEllipse
void void
DisplayDriverPainter::StrokeEllipse(const BRect &r, const DrawData *d) DisplayDriverPainter::StrokeEllipse(BRect r, const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); make_rect_valid(r);
BRect clipped = r;
fPainter->SetDrawData(d); extend_by_stroke_width(clipped, d);
clipped = fPainter->ClipRect(clipped);
float xRadius = r.Width() / 2.0; if (clipped.IsValid()) {
float yRadius = r.Height() / 2.0; fGraphicsCard->HideSoftwareCursor(r);
BPoint center(r.left + xRadius,
r.top + yRadius); fPainter->SetDrawData(d);
BRect touched = fPainter->StrokeEllipse(center, xRadius, yRadius); float xRadius = r.Width() / 2.0;
float yRadius = r.Height() / 2.0;
fGraphicsCard->Invalidate(touched); BPoint center(r.left + xRadius,
fGraphicsCard->ShowSoftwareCursor(); r.top + yRadius);
fPainter->StrokeEllipse(center, xRadius, yRadius);
fGraphicsCard->Invalidate(clipped);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -737,10 +793,8 @@ void
DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, const RGBColor &color) DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, const RGBColor &color)
{ {
if (Lock()) { if (Lock()) {
BRect touched(min_c(start.x, end.x), BRect touched(start, end);
min_c(start.y, end.y), make_rect_valid(touched);
max_c(start.x, end.x),
max_c(start.y, end.y));
touched = fPainter->ClipRect(touched); touched = fPainter->ClipRect(touched);
fGraphicsCard->HideSoftwareCursor(touched); fGraphicsCard->HideSoftwareCursor(touched);
@@ -762,17 +816,18 @@ void
DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, DrawData* context) DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, DrawData* context)
{ {
if (Lock()) { if (Lock()) {
BRect touched(min_c(start.x, end.x), BRect touched(start, end);
min_c(start.y, end.y), make_rect_valid(touched);
max_c(start.x, end.x), extend_by_stroke_width(touched, context);
max_c(start.y, end.y));
touched = fPainter->ClipRect(touched); touched = fPainter->ClipRect(touched);
fGraphicsCard->HideSoftwareCursor(touched); if (touched.IsValid()) {
fGraphicsCard->HideSoftwareCursor(touched);
touched = fPainter->StrokeLine(start, end, context);
touched = fPainter->StrokeLine(start, end, context);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -788,24 +843,41 @@ DisplayDriverPainter::StrokeLineArray(const int32 &numlines,
return; return;
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); // figure out bounding box for line array
const LineArrayData *data = (const LineArrayData *)&(linedata[0]);
DrawData context; BRect touched(min_c(data->pt1.x, data->pt2.x),
context.SetDrawingMode(B_OP_COPY); min_c(data->pt1.y, data->pt2.y),
const LineArrayData *data; max_c(data->pt1.x, data->pt2.x),
max_c(data->pt1.y, data->pt2.y));
data = (const LineArrayData *)&(linedata[0]);
context.SetHighColor(data->color);
BRect touched = fPainter->StrokeLine(data->pt1, data->pt2, &context);
for (int32 i = 1; i < numlines; i++) { for (int32 i = 1; i < numlines; i++) {
data = (const LineArrayData *)&(linedata[i]); data = (const LineArrayData *)&(linedata[i]);
context.SetHighColor(data->color); BRect box(min_c(data->pt1.x, data->pt2.x),
touched = touched | fPainter->StrokeLine(data->pt1, data->pt2, &context); min_c(data->pt1.y, data->pt2.y),
max_c(data->pt1.x, data->pt2.x),
max_c(data->pt1.y, data->pt2.y));
touched = touched | box;
}
extend_by_stroke_width(touched, d);
touched = fPainter->ClipRect(touched);
if (touched.IsValid()) {
fGraphicsCard->HideSoftwareCursor(touched);
DrawData context;
context.SetDrawingMode(B_OP_COPY);
data = (const LineArrayData *)&(linedata[0]);
context.SetHighColor(data->color);
fPainter->StrokeLine(data->pt1, data->pt2, &context);
for (int32 i = 1; i < numlines; i++) {
data = (const LineArrayData *)&(linedata[i]);
context.SetHighColor(data->color);
fPainter->StrokeLine(data->pt1, data->pt2, &context);
}
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
} }
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
Unlock(); Unlock();
} }
@@ -829,18 +901,22 @@ DisplayDriverPainter::StrokePoint(const BPoint& pt, DrawData *context)
// StrokePolygon // StrokePolygon
void void
DisplayDriverPainter::StrokePolygon(BPoint *ptlist, int32 numpts, DisplayDriverPainter::StrokePolygon(BPoint* ptlist, int32 numpts,
const BRect &bounds, const DrawData *d, BRect bounds, const DrawData* d,
bool closed) bool closed)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); extend_by_stroke_width(bounds, d);
bounds = fPainter->ClipRect(bounds);
fPainter->SetDrawData(d); if (bounds.IsValid()) {
BRect touched = fPainter->StrokePolygon(ptlist, numpts, closed); fGraphicsCard->HideSoftwareCursor(bounds);
fGraphicsCard->Invalidate(touched); fPainter->SetDrawData(d);
fGraphicsCard->ShowSoftwareCursor(); fPainter->StrokePolygon(ptlist, numpts, closed);
fGraphicsCard->Invalidate(bounds);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -850,29 +926,27 @@ DisplayDriverPainter::StrokePolygon(BPoint *ptlist, int32 numpts,
// //
// this function is used to draw a one pixel wide rect // this function is used to draw a one pixel wide rect
void void
DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color) DisplayDriverPainter::StrokeRect(BRect r, const RGBColor &color)
{ {
if (Lock()) { if (Lock()) {
// support invalid rects make_rect_valid(r);
BRect vr(min_c(r.left, r.right), BRect clipped = fPainter->ClipRect(r);
min_c(r.top, r.bottom), if (clipped.IsValid()) {
max_c(r.left, r.right),
max_c(r.top, r.bottom));
fGraphicsCard->HideSoftwareCursor(vr); fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->StrokeRect(vr, color.GetColor32()); fPainter->StrokeRect(r, color.GetColor32());
/* fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(vr.left, vr.top, fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.top,
vr.right, vr.top))); r.right, r.top)));
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(vr.left, vr.top + 1, fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.top + 1,
vr.left, vr.bottom - 1))); r.left, r.bottom - 1)));
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(vr.right, vr.top + 1, fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.right, r.top + 1,
vr.right, vr.bottom - 1))); r.right, r.bottom - 1)));
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(vr.left, vr.bottom, fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.bottom,
vr.right, vr.bottom)));*/ r.right, r.bottom)));
fGraphicsCard->Invalidate(fPainter->ClipRect(vr)); fGraphicsCard->ShowSoftwareCursor();
fGraphicsCard->ShowSoftwareCursor(); }
Unlock(); Unlock();
} }
@@ -880,24 +954,24 @@ DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color)
// StrokeRect // StrokeRect
void void
DisplayDriverPainter::StrokeRect(const BRect &r, const DrawData *d) DisplayDriverPainter::StrokeRect(BRect r, const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
// support invalid rects // support invalid rects
BRect vr(min_c(r.left, r.right), make_rect_valid(r);
min_c(r.top, r.bottom), BRect clipped(r);
max_c(r.left, r.right), extend_by_stroke_width(clipped, d);
max_c(r.top, r.bottom)); clipped = fPainter->ClipRect(clipped);
float extend = -ceilf(d->PenSize() / 2.0); if (clipped.IsValid()) {
vr.InsetBy(extend, extend);
fGraphicsCard->HideSoftwareCursor(clipped);
fGraphicsCard->HideSoftwareCursor(vr);
fPainter->SetDrawData(d);
fPainter->SetDrawData(d); fPainter->StrokeRect(r);
BRect touched = fPainter->StrokeRect(r);
fGraphicsCard->Invalidate(clipped);
fGraphicsCard->Invalidate(touched); fGraphicsCard->ShowSoftwareCursor();
fGraphicsCard->ShowSoftwareCursor(); }
Unlock(); Unlock();
} }
@@ -908,37 +982,48 @@ void
DisplayDriverPainter::StrokeRegion(BRegion& r, const DrawData *d) DisplayDriverPainter::StrokeRegion(BRegion& r, const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); BRect clipped(r.Frame());
extend_by_stroke_width(clipped, d);
fPainter->SetDrawData(d); clipped = fPainter->ClipRect(clipped);
if (clipped.IsValid()) {
BRect touched = fPainter->StrokeRect(r.RectAt(0)); fGraphicsCard->HideSoftwareCursor(clipped);
int32 count = r.CountRects(); fPainter->SetDrawData(d);
for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->StrokeRect(r.RectAt(i)); BRect touched = fPainter->StrokeRect(r.RectAt(0));
int32 count = r.CountRects();
for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->StrokeRect(r.RectAt(i));
}
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
} }
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
Unlock(); Unlock();
} }
} }
// StrokeRoundRect // StrokeRoundRect
void void
DisplayDriverPainter::StrokeRoundRect(const BRect &r, const float &xrad, DisplayDriverPainter::StrokeRoundRect(BRect r, const float &xrad,
const float &yrad, const DrawData *d) const float &yrad, const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); // NOTE: the stroke does not extend past "r" in R5,
// though I consider this unexpected behaviour.
fPainter->SetDrawData(d); make_rect_valid(r);
BRect touched = fPainter->StrokeRoundRect(r, xrad, yrad); BRect clipped = fPainter->ClipRect(r);
if (clipped.IsValid()) {
fGraphicsCard->Invalidate(touched); fGraphicsCard->HideSoftwareCursor(clipped);
fGraphicsCard->ShowSoftwareCursor();
fPainter->SetDrawData(d);
BRect touched = fPainter->StrokeRoundRect(r, xrad, yrad);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
@@ -964,18 +1049,23 @@ DisplayDriverPainter::StrokeTriangle(BPoint *pts, const BRect &bounds,
const DrawData *d) const DrawData *d)
{ {
if (Lock()) { if (Lock()) {
fGraphicsCard->HideSoftwareCursor(); BRect clipped(bounds);
extend_by_stroke_width(clipped, d);
fPainter->SetDrawData(d); clipped = fPainter->ClipRect(clipped);
BRect touched = fPainter->StrokeTriangle(pts[0], pts[1], pts[2]); if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fPainter->SetDrawData(d);
fPainter->StrokeTriangle(pts[0], pts[1], pts[2]);
fGraphicsCard->Invalidate(clipped);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock(); Unlock();
} }
} }
/*
// DrawString // DrawString
void void
DisplayDriverPainter::DrawString(const char *string, const int32 &length, DisplayDriverPainter::DrawString(const char *string, const int32 &length,
@@ -985,18 +1075,16 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
static DrawData d; static DrawData d;
d.SetHighColor(color); d.SetHighColor(color);
// TODO: Why is escapement_delta a part of the state stack?
if (delta)
d.SetEscapementDelta(*delta);
DrawString(string, length, pt, &d); DrawString(string, length, pt, &d);
} }
*/
// DrawString // DrawString
void void
DisplayDriverPainter::DrawString(const char *string, const int32 &length, DisplayDriverPainter::DrawString(const char* string, int32 length,
const BPoint &pt, DrawData *d) const BPoint& pt, DrawData* d,
escapement_delta* delta)
{ {
// TODO: use delta
if (Lock()) { if (Lock()) {
fPainter->SetDrawData(d); fPainter->SetDrawData(d);
//bigtime_t now = system_time(); //bigtime_t now = system_time();
@@ -1007,7 +1095,8 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
// in case we don't have one. // in case we don't have one.
BRect b = fPainter->BoundingBox(string, length, pt); BRect b = fPainter->BoundingBox(string, length, pt);
// stop here if we're supposed to render outside of the clipping // stop here if we're supposed to render outside of the clipping
if (fPainter->ClippingRegion()->Frame().Intersects(b)) { b = fPainter->ClipRect(b);
if (b.IsValid()) {
//printf("bounding box '%s': %lld µs\n", string, system_time() - now); //printf("bounding box '%s': %lld µs\n", string, system_time() - now);
fGraphicsCard->HideSoftwareCursor(b); fGraphicsCard->HideSoftwareCursor(b);
@@ -1024,9 +1113,11 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
// StringWidth // StringWidth
float float
DisplayDriverPainter::StringWidth(const char *string, int32 length, DisplayDriverPainter::StringWidth(const char* string, int32 length,
const DrawData *d) const DrawData* d,
escapement_delta* delta)
{ {
// TODO: use delta
float width = 0.0; float width = 0.0;
if (Lock()) { if (Lock()) {
fPainter->SetDrawData(d); fPainter->SetDrawData(d);
@@ -1038,9 +1129,11 @@ DisplayDriverPainter::StringWidth(const char *string, int32 length,
// StringWidth // StringWidth
float float
DisplayDriverPainter::StringWidth(const char *string, int32 length, DisplayDriverPainter::StringWidth(const char* string, int32 length,
const ServerFont &font) const ServerFont& font,
escapement_delta* delta)
{ {
// TODO: use delta
static DrawData d; static DrawData d;
d.SetFont(font); d.SetFont(font);
return StringWidth(string, length, &d); return StringWidth(string, length, &d);
+32 -28
View File
@@ -16,12 +16,11 @@
#include "DisplayDriver.h" #include "DisplayDriver.h"
class HWInterface;
class Painter; class Painter;
class DisplayDriverPainter : public DisplayDriver { class DisplayDriverPainter : public DisplayDriver {
public: public:
DisplayDriverPainter(HWInterface* hwInterface); DisplayDriverPainter(HWInterface* interface = NULL);
virtual ~DisplayDriverPainter(); virtual ~DisplayDriverPainter();
// when implementing, be sure to call the inherited version // when implementing, be sure to call the inherited version
@@ -30,6 +29,8 @@ public:
virtual void Update(); virtual void Update();
virtual void SetHWInterface(HWInterface* interface);
// clipping for all drawing functions, passing a NULL region // clipping for all drawing functions, passing a NULL region
// will remove any clipping (drawing allowed everywhere) // will remove any clipping (drawing allowed everywhere)
virtual void ConstrainClippingRegion(BRegion* region); virtual void ConstrainClippingRegion(BRegion* region);
@@ -44,14 +45,14 @@ public:
int32 rCount, int32 rCount,
BRegion* clipReg); BRegion* clipReg);
virtual void InvertRect( const BRect &r); virtual void InvertRect( BRect r);
virtual void DrawBitmap( ServerBitmap *bitmap, virtual void DrawBitmap( ServerBitmap *bitmap,
const BRect &source, const BRect &source,
const BRect &dest, const BRect &dest,
const DrawData *d); const DrawData *d);
virtual void FillArc( const BRect &r, virtual void FillArc( BRect r,
const float &angle, const float &angle,
const float &span, const float &span,
const DrawData *d); const DrawData *d);
@@ -59,24 +60,24 @@ public:
virtual void FillBezier( BPoint *pts, virtual void FillBezier( BPoint *pts,
const DrawData *d); const DrawData *d);
virtual void FillEllipse( const BRect &r, virtual void FillEllipse( BRect r,
const DrawData *d); const DrawData *d);
virtual void FillPolygon( BPoint *ptlist, virtual void FillPolygon( BPoint *ptlist,
int32 numpts, int32 numpts,
const BRect &bounds, BRect bounds,
const DrawData *d); const DrawData *d);
virtual void FillRect( const BRect &r, virtual void FillRect( BRect r,
const RGBColor &color); const RGBColor &color);
virtual void FillRect( const BRect &r, virtual void FillRect( BRect r,
const DrawData *d); const DrawData *d);
virtual void FillRegion( BRegion &r, virtual void FillRegion( BRegion &r,
const DrawData *d); const DrawData *d);
virtual void FillRoundRect( const BRect &r, virtual void FillRoundRect( BRect r,
const float &xrad, const float &xrad,
const float &yrad, const float &yrad,
const DrawData *d); const DrawData *d);
@@ -89,10 +90,10 @@ public:
const DrawData *d); const DrawData *d);
virtual void FillTriangle( BPoint *pts, virtual void FillTriangle( BPoint *pts,
const BRect &bounds, BRect bounds,
const DrawData *d); const DrawData *d);
virtual void StrokeArc( const BRect &r, virtual void StrokeArc( BRect r,
const float &angle, const float &angle,
const float &span, const float &span,
const DrawData *d); const DrawData *d);
@@ -100,7 +101,7 @@ public:
virtual void StrokeBezier( BPoint *pts, virtual void StrokeBezier( BPoint *pts,
const DrawData *d); const DrawData *d);
virtual void StrokeEllipse( const BRect &r, virtual void StrokeEllipse( BRect r,
const DrawData *d); const DrawData *d);
// this version used by Decorator // this version used by Decorator
@@ -125,21 +126,21 @@ public:
virtual void StrokePolygon( BPoint *ptlist, virtual void StrokePolygon( BPoint *ptlist,
int32 numpts, int32 numpts,
const BRect &bounds, BRect bounds,
const DrawData *d, const DrawData *d,
bool is_closed=true); bool is_closed=true);
// this version used by Decorator // this version used by Decorator
virtual void StrokeRect( const BRect &r, virtual void StrokeRect( BRect r,
const RGBColor &color); const RGBColor &color);
virtual void StrokeRect( const BRect &r, virtual void StrokeRect( BRect r,
const DrawData *d); const DrawData *d);
virtual void StrokeRegion( BRegion &r, virtual void StrokeRegion( BRegion &r,
const DrawData *d); const DrawData *d);
virtual void StrokeRoundRect(const BRect &r, virtual void StrokeRoundRect(BRect r,
const float &xrad, const float &xrad,
const float &yrad, const float &yrad,
const DrawData *d); const DrawData *d);
@@ -158,28 +159,31 @@ public:
// Font-related calls // Font-related calls
// DrawData is NOT const because this call updates the pen position in the passed DrawData // DrawData is NOT const because this call updates the pen position in the passed DrawData
virtual void DrawString( const char *string, virtual void DrawString( const char* string,
const int32 &length, int32 length,
const BPoint &pt, const BPoint& pt,
DrawData *d); DrawData* d,
escapement_delta* delta = NULL);
virtual void DrawString( const char *string, /* virtual void DrawString( const char *string,
const int32 &length, const int32 &length,
const BPoint &pt, const BPoint &pt,
const RGBColor &color, const RGBColor &color,
escapement_delta *delta=NULL); escapement_delta *delta=NULL);*/
virtual float StringWidth( const char *string, virtual float StringWidth( const char* string,
int32 length, int32 length,
const DrawData *d); const DrawData* d,
escapement_delta* delta = NULL);
virtual float StringWidth( const char *string, virtual float StringWidth( const char* string,
int32 length, int32 length,
const ServerFont &font); const ServerFont& font,
escapement_delta* delta = NULL);
virtual float StringHeight( const char *string, virtual float StringHeight( const char* string,
int32 length, int32 length,
const DrawData *d); const DrawData* d);
virtual bool Lock(); virtual bool Lock();
virtual void Unlock(); virtual void Unlock();
+12 -21
View File
@@ -3,12 +3,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifndef __HAIKU__
#include <Screen.h>
#endif
#include "RenderingBuffer.h" #include "RenderingBuffer.h"
#include "ServerCursor.h" #include "ServerCursor.h"
#include "SystemPalette.h"
#include "UpdateQueue.h" #include "UpdateQueue.h"
#include "HWInterface.h" #include "HWInterface.h"
@@ -176,7 +173,7 @@ HWInterface::CopyBackToFront(const BRect& frame)
// we need to mess with the area, but it is const // we need to mess with the area, but it is const
BRect area(frame); BRect area(frame);
BRect bufferClip(0.0, 0.0, backBuffer->Width() - 1, backBuffer->Height() - 1); BRect bufferClip(backBuffer->Bounds());
if (area.IsValid() && area.Intersects(bufferClip)) { if (area.IsValid() && area.Intersects(bufferClip)) {
@@ -213,6 +210,8 @@ HWInterface::HideSoftwareCursor(const BRect& area)
fCursorAreaBackup->right, fCursorAreaBackup->right,
fCursorAreaBackup->bottom); fCursorAreaBackup->bottom);
if (area.Intersects(backupArea)) { if (area.Intersects(backupArea)) {
//printf("HideSoftwareCursor(BRect(%.1, %.1, %.1, %.1))\n", area.left, area.top, area.right, area.bottom);
//backupArea.PrintToStream();
_RestoreCursorArea(backupArea); _RestoreCursorArea(backupArea);
fSoftwareCursorHidden = true; fSoftwareCursorHidden = true;
} }
@@ -224,6 +223,7 @@ void
HWInterface::HideSoftwareCursor() HWInterface::HideSoftwareCursor()
{ {
if (fCursorAreaBackup && !fSoftwareCursorHidden) { if (fCursorAreaBackup && !fSoftwareCursorHidden) {
//printf("HideSoftwareCursor()\n");
_RestoreCursorArea(BRect(fCursorAreaBackup->left, _RestoreCursorArea(BRect(fCursorAreaBackup->left,
fCursorAreaBackup->top, fCursorAreaBackup->top,
fCursorAreaBackup->right, fCursorAreaBackup->right,
@@ -237,6 +237,7 @@ void
HWInterface::ShowSoftwareCursor() HWInterface::ShowSoftwareCursor()
{ {
if (fCursorAreaBackup && fSoftwareCursorHidden) { if (fCursorAreaBackup && fSoftwareCursorHidden) {
//printf("ShowSoftwareCursor()\n");
_DrawCursor(_CursorFrame()); _DrawCursor(_CursorFrame());
fSoftwareCursorHidden = false; fSoftwareCursorHidden = false;
} }
@@ -258,8 +259,7 @@ HWInterface::_DrawCursor(BRect area) const
BRect cf = _CursorFrame(); BRect cf = _CursorFrame();
// make sure we don't copy out of bounds // make sure we don't copy out of bounds
BRect bufferClip(0.0, 0.0, backBuffer->Width() - 1, backBuffer->Height() - 1); area = backBuffer->Bounds() & area;
area = bufferClip & area;
if (cf.IsValid() && area.Intersects(cf)) { if (cf.IsValid() && area.Intersects(cf)) {
// clip to common area // clip to common area
@@ -545,35 +545,26 @@ HWInterface::_CopyToFront(uint8* src, uint32 srcBPR,
break; break;
} }
case B_CMAP8: { case B_CMAP8: {
// TODO: make this work on Haiku, the problem is only const color_map *colorMap = SystemColorMap();
// the rgb_color->index mapping, there is an implementation
// in Bitmap.cpp, maybe it needs to be moved to a public
// place...
#ifndef __HAIKU__
// offset to left top pixel in dest buffer // offset to left top pixel in dest buffer
dst += y * dstBPR + x; dst += y * dstBPR + x;
int32 left = x; int32 left = x;
uint16 index;
// copy // copy
// TODO: using BScreen will not be an option in the
// final implementation, will it? The BBitmap implementation
// has a class that handles this, something so useful
// should be moved to a more public place.
// TODO: assumes BGR order again // TODO: assumes BGR order again
BScreen screen;
for (; y <= bottom; y++) { for (; y <= bottom; y++) {
uint8* srcHandle = src; uint8* srcHandle = src;
uint8* dstHandle = dst; uint8* dstHandle = dst;
for (x = left; x <= right; x++) { for (x = left; x <= right; x++) {
*dstHandle = screen.IndexForColor(srcHandle[2], index = ((srcHandle[2] & 0xf8) << 7) | ((srcHandle[1] & 0xf8) << 2) | (srcHandle[1] >> 3);
srcHandle[1], *dstHandle = colorMap->index_map[index];
srcHandle[0]);
dstHandle ++; dstHandle ++;
srcHandle += 4; srcHandle += 4;
} }
dst += dstBPR; dst += dstBPR;
src += srcBPR; src += srcBPR;
} }
#endif // __HAIKU__
break; break;
} }
case B_GRAY8: { case B_GRAY8: {
+4 -5
View File
@@ -1,10 +1,9 @@
// //------------------------------------------------------------------------------
// Copyright 2005, Stephan Aßmus <[email protected]> // Copyright 2005, Haiku, Inc. All rights reserved.
// Distributed under the terms of the MIT License. // Distributed under the terms of the MIT License.
// //
// Contains an abstract base class HWInterface that provides the // Author: Stephan Aßmus, <[email protected]>
// basic functionality for frame buffer acces in the DisplayDriverPainter //------------------------------------------------------------------------------
// implementation.
#ifndef HW_INTERFACE_H #ifndef HW_INTERFACE_H
#define HW_INTERFACE_H #define HW_INTERFACE_H
+15 -6
View File
@@ -175,15 +175,18 @@ Painter::DetachFromBuffer()
void void
Painter::SetDrawData(const DrawData* data) Painter::SetDrawData(const DrawData* data)
{ {
// for now... // NOTE: The custom clipping in "data" is ignored, because it has already been
// taken into account elsewhere
// TODO: optimize "context switch" for speed...
// but for now...
SetPenSize(data->PenSize()); SetPenSize(data->PenSize());
SetPenLocation(data->PenLocation()); SetPenLocation(data->PenLocation());
SetFont(data->Font()); SetFont(data->Font());
// fTextRenderer->SetAntialiasing(data->FontAntiAliasing()); fTextRenderer->SetAntialiasing(!(data->ForceFontAliasing() || data->Font().Flags() & B_DISABLE_ANTIALIASING));
fTextRenderer->SetAntialiasing(!(data->Font().Flags() & B_DISABLE_ANTIALIASING));
// if (data->clipReg) { fSubpixelPrecise = data->SubPixelPrecise();
// ConstrainClipping(*data->clipReg);
// }
// any of these conditions means we need to use a different drawing // any of these conditions means we need to use a different drawing
// mode instance // mode instance
bool updateDrawingMode = !(data->GetPattern() == fPatternHandler->GetPattern()) || bool updateDrawingMode = !(data->GetPattern() == fPatternHandler->GetPattern()) ||
@@ -1482,6 +1485,12 @@ Painter::_StrokePath(VertexSource& path) const
// stroke.line_cap(agg::butt_cap); // stroke.line_cap(agg::butt_cap);
stroke.width(fPenSize); stroke.width(fPenSize);
// special case line width = 1 with square caps
// this has a couple of advantages and it looks
// like this is also the R5 behaviour.
if (fPenSize == 1.0)
stroke.line_cap(agg::square_cap);
fRasterizer->reset(); fRasterizer->reset();
fRasterizer->add_path(stroke); fRasterizer->add_path(stroke);
agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer); agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer);
@@ -83,11 +83,6 @@ class Painter {
void SetPenLocation(const BPoint& location); void SetPenLocation(const BPoint& location);
void SetFont(const ServerFont& font); void SetFont(const ServerFont& font);
// BView API compatibility (for easier testing)
void Sync() {}
inline void MovePenTo(const BPoint& location)
{ SetPenLocation(location); }
// painting functions // painting functions
// lines // lines
@@ -98,7 +93,7 @@ class Painter {
BRect StrokeLine( BPoint b, BRect StrokeLine( BPoint b,
DrawData* context); DrawData* context);
// return true if the line was either vertical or horizontal // returns true if the line was either vertical or horizontal
// draws a solid one pixel wide line of color c, no blending // draws a solid one pixel wide line of color c, no blending
bool StraightLine( BPoint a, bool StraightLine( BPoint a,
BPoint b, BPoint b,
@@ -288,8 +283,7 @@ class Painter {
agg::line_profile_aa fLineProfile; agg::line_profile_aa fLineProfile;
// for internal coordinate rounding/transformation, // for internal coordinate rounding/transformation
// does not concern rendering
bool fSubpixelPrecise; bool fSubpixelPrecise;
float fPenSize; float fPenSize;
@@ -306,8 +300,7 @@ class Painter {
ServerFont fFont; ServerFont fFont;
// a class handling rendering and caching of glyphs // a class handling rendering and caching of glyphs
// it is setup to load from a specific Freetype supported // it is setup to load from a specific Freetype supported
// font file, it uses the FontManager to locate a file // font file which it gets from ServerFont
// by Family and Style
AGGTextRenderer* fTextRenderer; AGGTextRenderer* fTextRenderer;
}; };
@@ -1,73 +0,0 @@
// ViewBitmapBuffer.h
#include <Bitmap.h>
#include "ViewBitmapBuffer.h"
// constructor
ViewBitmapBuffer::ViewBitmapBuffer(BBitmap* bitmap)
: fBitmap(bitmap)
{
}
// destructor
ViewBitmapBuffer::~ViewBitmapBuffer()
{
delete fBitmap;
}
// InitCheck
status_t
ViewBitmapBuffer::InitCheck() const
{
status_t ret = B_NO_INIT;
if (fBitmap)
ret = fBitmap->InitCheck();
return ret;
}
// ColorSpace
color_space
ViewBitmapBuffer::ColorSpace() const
{
if (InitCheck() >= B_OK)
return fBitmap->ColorSpace();
return B_NO_COLOR_SPACE;
}
// Bits
void*
ViewBitmapBuffer::Bits() const
{
if (InitCheck() >= B_OK)
return fBitmap->Bits();
return NULL;
}
// BytesPerRow
uint32
ViewBitmapBuffer::BytesPerRow() const
{
if (InitCheck() >= B_OK)
return fBitmap->BytesPerRow();
return 0;
}
// Width
uint32
ViewBitmapBuffer::Width() const
{
if (InitCheck() >= B_OK)
return fBitmap->Bounds().IntegerWidth() + 1;
return 0;
}
// Height
uint32
ViewBitmapBuffer::Height() const
{
if (InitCheck() >= B_OK)
return fBitmap->Bounds().IntegerHeight() + 1;
return 0;
}
@@ -1,31 +0,0 @@
// ViewBitmapBuffer.h
#ifndef VIEW_BITMAP_BUFFER_H
#define VIEW_BITMAP_BUFFER_H
#include "RenderingBuffer.h"
class BBitmap;
class ViewBitmapBuffer : public RenderingBuffer {
public:
ViewBitmapBuffer(BBitmap* bitmap);
virtual ~ViewBitmapBuffer();
virtual status_t InitCheck() const;
virtual color_space ColorSpace() const;
virtual void* Bits() const;
virtual uint32 BytesPerRow() const;
virtual uint32 Width() const;
virtual uint32 Height() const;
// ViewBitmapBuffer
const BBitmap* Bitmap() const
{ return fBitmap; }
private:
BBitmap* fBitmap;
};
#endif // VIEW_BITMAP_BUFFER_H
+2 -2
View File
@@ -299,8 +299,8 @@ STRACE("MSG_UPDATE\n");
}*/ }*/
BRect frame = fUpdateRegion.Frame(); BRect frame = fUpdateRegion.Frame();
if (frame.IsValid()) { if (frame.IsValid()) {
// fView->Invalidate(frame); fView->Invalidate(frame);
fView->Invalidate(); // fView->Invalidate();
} }
fUpdateRegion.MakeEmpty(); fUpdateRegion.MakeEmpty();
fUpdateLock.Unlock(); fUpdateLock.Unlock();