diff --git a/headers/private/interface/ViewPrivate.h b/headers/private/interface/ViewPrivate.h index 9a04ac3a2e..5ad8f5c308 100644 --- a/headers/private/interface/ViewPrivate.h +++ b/headers/private/interface/ViewPrivate.h @@ -15,6 +15,7 @@ #include #include #include +#include const static uint32 kDeleteReplicant = 'JAHA'; @@ -121,21 +122,13 @@ ViewState::IsAllValid() const } // namespace BPrivate -struct _array_hdr_{ - float startX; - float startY; - float endX; - float endY; - rgb_color color; -}; - struct _array_data_{ // the max number of points in the array - uint32 maxCount; + uint32 maxCount; // the current number of points in the array - uint32 count; + uint32 count; // the array of points - _array_hdr_* array; + ViewLineArrayInfo* array; }; #endif /* VIEW_PRIVATE_H */ diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index 66a17ca421..d8d0dd765a 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -216,22 +217,27 @@ ViewState::UpdateServerState(BPrivate::PortLink &link) UpdateServerFontState(link); link.StartMessage(AS_VIEW_SET_STATE); - link.Attach(pen_location); - link.Attach(pen_size); - link.Attach(high_color); - link.Attach(low_color); - link.Attach< ::pattern>(pattern); - link.Attach((int8)drawing_mode); - link.Attach(origin); - link.Attach((int8)line_join); - link.Attach((int8)line_cap); - link.Attach(miter_limit); - link.Attach((int8)alpha_source_mode); - link.Attach((int8)alpha_function_mode); - link.Attach(scale); - link.Attach(font_aliasing); + + ViewSetStateInfo info; + info.penLocation = pen_location; + info.penSize = pen_size; + info.highColor = high_color; + info.lowColor = low_color; + info.pattern = pattern; + info.drawingMode = drawing_mode; + info.origin = origin; + info.scale = scale; + info.lineJoin = line_join; + info.lineCap = line_cap; + info.miterLimit = miter_limit; + info.alphaSourceMode = alpha_source_mode; + info.alphaFunctionMode = alpha_function_mode; + info.fontAntialiasing = font_aliasing; + link.Attach(info); // we send the 'local' clipping region... if we have one... + // TODO: Could be optimized, but is low prio, since most views won't + // have a custom clipping region. if (clipping_region_used) { int32 count = clipping_region.CountRects(); link.Attach(count); @@ -260,57 +266,36 @@ ViewState::UpdateFrom(BPrivate::PortLink &link) || code != B_OK) return; - uint32 fontID; - float size; - float shear; - float rotation; - float falseBoldeWidth; - uint8 spacing; - uint8 encoding; - uint16 face; - uint32 flags; - - // read and set the font state - link.Read((int32 *)&fontID); - link.Read(&size); - link.Read(&shear); - link.Read(&rotation); - link.Read(&falseBoldeWidth); - link.Read((int8 *)&spacing); - link.Read((int8 *)&encoding); - link.Read((int16 *)&face); - link.Read((int32 *)&flags); + ViewGetStateInfo info; + link.Read(&info); + // set view's font state font_flags = B_FONT_ALL; - font.SetFamilyAndStyle(fontID); - font.SetSize(size); - font.SetShear(shear); - font.SetRotation(rotation); - font.SetFalseBoldWidth(falseBoldeWidth); - font.SetSpacing(spacing); - font.SetEncoding(encoding); - font.SetFace(face); - font.SetFlags(flags); + font.SetFamilyAndStyle(info.fontID); + font.SetSize(info.fontSize); + font.SetShear(info.fontShear); + font.SetRotation(info.fontRotation); + font.SetFalseBoldWidth(info.fontFalseBoldWidth); + font.SetSpacing(info.fontSpacing); + font.SetEncoding(info.fontEncoding); + font.SetFace(info.fontFace); + font.SetFlags(info.fontFlags); - // read and set view's state - link.Read(&pen_location); - link.Read(&pen_size); - link.Read(&high_color); - link.Read(&low_color); - link.Read< ::pattern>(&pattern); - link.Read(&origin); - - int8 drawingMode; - link.Read((int8 *)&drawingMode); - drawing_mode = (::drawing_mode)drawingMode; - - link.Read((int8 *)&line_cap); - link.Read((int8 *)&line_join); - link.Read(&miter_limit); - link.Read((int8 *)&alpha_source_mode); - link.Read((int8 *)&alpha_function_mode); - link.Read(&scale); - link.Read(&font_aliasing); + // set view's state + pen_location = info.viewStateInfo.penLocation; + pen_size = info.viewStateInfo.penSize; + high_color = info.viewStateInfo.highColor; + low_color = info.viewStateInfo.lowColor; + pattern = info.viewStateInfo.pattern; + drawing_mode = info.viewStateInfo.drawingMode; + origin = info.viewStateInfo.origin; + scale = info.viewStateInfo.scale; + line_join = info.viewStateInfo.lineJoin; + line_cap = info.viewStateInfo.lineCap; + miter_limit = info.viewStateInfo.miterLimit; + alpha_source_mode = info.viewStateInfo.alphaSourceMode; + alpha_function_mode = info.viewStateInfo.alphaFunctionMode; + font_aliasing = info.viewStateInfo.fontAntialiasing; // read the user clipping // (that's NOT the current View visible clipping but the additional @@ -796,6 +781,7 @@ BView::_ConvertFromScreen(BPoint *pt, bool checkLock) const fParent->_ConvertFromScreen(pt, false); } + void BView::ConvertFromScreen(BPoint *pt) const { @@ -1017,8 +1003,10 @@ BView::SetViewCursor(const BCursor *cursor, bool sync) _CheckLockAndSwitchCurrent(); fOwner->fLink->StartMessage(AS_VIEW_SET_CURSOR); - fOwner->fLink->Attach(cursor->fServerToken); - fOwner->fLink->Attach(sync); + ViewSetViewCursorInfo info; + info.cursorToken = cursor->fServerToken; + info.sync = sync; + fOwner->fLink->Attach(info); if (!sync) { cursor->fPendingViewCursor = true; @@ -1781,10 +1769,13 @@ BView::SetLineMode(cap_mode lineCap, join_mode lineJoin, float miterLimit) if (fOwner) { _CheckLockAndSwitchCurrent(); + ViewSetLineModeInfo info; + info.lineJoin = lineJoin; + info.lineCap = lineCap; + info.miterLimit = miterLimit; + fOwner->fLink->StartMessage(AS_VIEW_SET_LINE_MODE); - fOwner->fLink->Attach((int8)lineCap); - fOwner->fLink->Attach((int8)lineJoin); - fOwner->fLink->Attach(miterLimit); + fOwner->fLink->Attach(info); fState->valid_flags |= B_VIEW_LINE_MODES_BIT; } @@ -1830,13 +1821,13 @@ BView::LineMiterLimit() const int32 code; if (fOwner->fLink->FlushWithReply(code) == B_OK && code == B_OK) { - int8 cap, join; - fOwner->fLink->Read((int8 *)&cap); - fOwner->fLink->Read((int8 *)&join); - fOwner->fLink->Read(&fState->miter_limit); - fState->line_cap = (cap_mode)cap; - fState->line_join = (join_mode)join; + ViewSetLineModeInfo info; + fOwner->fLink->Read(&info); + + fState->line_cap = info.lineCap; + fState->line_join = info.lineJoin; + fState->miter_limit = info.miterLimit; } fState->valid_flags |= B_VIEW_LINE_MODES_BIT; @@ -1901,9 +1892,12 @@ BView::SetBlendingMode(source_alpha sourceAlpha, alpha_function alphaFunction) if (fOwner) { _CheckLockAndSwitchCurrent(); + ViewBlendingModeInfo info; + info.sourceAlpha = sourceAlpha; + info.alphaFunction = alphaFunction; + fOwner->fLink->StartMessage(AS_VIEW_SET_BLENDING_MODE); - fOwner->fLink->Attach((int8)sourceAlpha); - fOwner->fLink->Attach((int8)alphaFunction); + fOwner->fLink->Attach(info); fState->valid_flags |= B_VIEW_BLENDING_BIT; } @@ -1926,12 +1920,11 @@ BView::GetBlendingMode(source_alpha *_sourceAlpha, int32 code; if (fOwner->fLink->FlushWithReply(code) == B_OK && code == B_OK) { - int8 alphaSourceMode, alphaFunctionMode; - fOwner->fLink->Read(&alphaSourceMode); - fOwner->fLink->Read(&alphaFunctionMode); + ViewBlendingModeInfo info; + fOwner->fLink->Read(&info); - fState->alpha_source_mode = (source_alpha)alphaSourceMode; - fState->alpha_function_mode = (alpha_function)alphaFunctionMode; + fState->alpha_source_mode = info.sourceAlpha; + fState->alpha_function_mode = info.alphaFunction; fState->valid_flags |= B_VIEW_BLENDING_BIT; } @@ -1963,8 +1956,7 @@ BView::MovePenTo(float x, float y) _CheckLockAndSwitchCurrent(); fOwner->fLink->StartMessage(AS_VIEW_SET_PEN_LOC); - fOwner->fLink->Attach(x); - fOwner->fLink->Attach(y); + fOwner->fLink->Attach(BPoint(x, y)); fState->valid_flags |= B_VIEW_PEN_LOCATION_BIT; } @@ -2387,11 +2379,14 @@ BView::DrawBitmapAsync(const BBitmap* bitmap, BRect bitmapRect, BRect viewRect, _CheckLockAndSwitchCurrent(); + ViewDrawBitmapInfo info; + info.bitmapToken = bitmap->_ServerToken(); + info.options = options; + info.viewRect = viewRect; + info.bitmapRect = bitmapRect; + fOwner->fLink->StartMessage(AS_VIEW_DRAW_BITMAP); - fOwner->fLink->Attach(bitmap->_ServerToken()); - fOwner->fLink->Attach(options); - fOwner->fLink->Attach(viewRect); - fOwner->fLink->Attach(bitmapRect); + fOwner->fLink->Attach(info); _FlushIfNotInTransaction(); } @@ -2422,15 +2417,14 @@ BView::DrawBitmapAsync(const BBitmap* bitmap, BPoint where) _CheckLockAndSwitchCurrent(); - BRect bitmapRect = bitmap->Bounds().OffsetToCopy(B_ORIGIN); - BRect viewRect = bitmapRect.OffsetToCopy(where); - uint32 options = 0; + ViewDrawBitmapInfo info; + info.bitmapToken = bitmap->_ServerToken(); + info.options = 0; + info.bitmapRect = bitmap->Bounds().OffsetToCopy(B_ORIGIN); + info.viewRect = info.bitmapRect.OffsetToCopy(where); fOwner->fLink->StartMessage(AS_VIEW_DRAW_BITMAP); - fOwner->fLink->Attach(bitmap->_ServerToken()); - fOwner->fLink->Attach(options); - fOwner->fLink->Attach(viewRect); - fOwner->fLink->Attach(bitmapRect); + fOwner->fLink->Attach(info); _FlushIfNotInTransaction(); } @@ -2533,33 +2527,33 @@ BView::DrawString(const char *string, int32 length, escapement_delta *delta) void -BView::DrawString(const char *string, int32 length, BPoint location, - escapement_delta *delta) +BView::DrawString(const char* string, int32 length, BPoint location, + escapement_delta* delta) { - if (string == NULL || length < 1) + if (fOwner == NULL || string == NULL || length < 1) return; - if (fOwner) { - _CheckLockAndSwitchCurrent(); + _CheckLockAndSwitchCurrent(); - // quite often delta will be NULL - if (delta) - fOwner->fLink->StartMessage(AS_DRAW_STRING_WITH_DELTA); - else - fOwner->fLink->StartMessage(AS_DRAW_STRING); - fOwner->fLink->Attach(length); - fOwner->fLink->Attach(location); + ViewDrawStringInfo info; + info.stringLength = length; + info.location = location; + if (delta != NULL) + info.delta = *delta; - if (delta) - fOwner->fLink->Attach(*delta); + // quite often delta will be NULL + if (delta) + fOwner->fLink->StartMessage(AS_DRAW_STRING_WITH_DELTA); + else + fOwner->fLink->StartMessage(AS_DRAW_STRING); - fOwner->fLink->AttachString(string, length); + fOwner->fLink->Attach(info); + fOwner->fLink->Attach(string, length); - _FlushIfNotInTransaction(); + _FlushIfNotInTransaction(); - // this modifies our pen location, so we invalidate the flag. - fState->valid_flags &= ~B_VIEW_PEN_LOCATION_BIT; - } + // this modifies our pen location, so we invalidate the flag. + fState->valid_flags &= ~B_VIEW_PEN_LOCATION_BIT; } @@ -3277,9 +3271,12 @@ BView::StrokeLine(BPoint pt0, BPoint pt1, ::pattern pattern) _CheckLockAndSwitchCurrent(); _UpdatePattern(pattern); + ViewStrokeLineInfo info; + info.startPoint = pt0; + info.endPoint = pt1; + fOwner->fLink->StartMessage(AS_STROKE_LINE); - fOwner->fLink->Attach(pt0); - fOwner->fLink->Attach(pt1); + fOwner->fLink->Attach(info); _FlushIfNotInTransaction(); @@ -3386,7 +3383,7 @@ BView::BeginLineArray(int32 count) fCommArray = new _array_data_; fCommArray->maxCount = count; fCommArray->count = 0; - fCommArray->array = new _array_hdr_[count]; + fCommArray->array = new ViewLineArrayInfo[count]; } @@ -3403,10 +3400,8 @@ BView::AddLine(BPoint pt0, BPoint pt1, rgb_color col) const uint32 &arrayCount = fCommArray->count; if (arrayCount < fCommArray->maxCount) { - fCommArray->array[arrayCount].startX = pt0.x; - fCommArray->array[arrayCount].startY = pt0.y; - fCommArray->array[arrayCount].endX = pt1.x; - fCommArray->array[arrayCount].endY = pt1.y; + fCommArray->array[arrayCount].startPoint = pt0; + fCommArray->array[arrayCount].endPoint = pt1; fCommArray->array[arrayCount].color = col; fCommArray->count++; @@ -3420,7 +3415,7 @@ BView::EndLineArray() if (fOwner == NULL) return; - if (!fCommArray) + if (fCommArray == NULL) debugger("Can't call EndLineArray before BeginLineArray"); _CheckLockAndSwitchCurrent(); @@ -3428,7 +3423,7 @@ BView::EndLineArray() fOwner->fLink->StartMessage(AS_STROKE_LINEARRAY); fOwner->fLink->Attach(fCommArray->count); fOwner->fLink->Attach(fCommArray->array, - fCommArray->count * sizeof(_array_hdr_)); + fCommArray->count * sizeof(ViewLineArrayInfo)); _FlushIfNotInTransaction(); diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index ade88cae62..f1c16c649f 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -12,6 +12,7 @@ //! Data classes for working with BView states and draw parameters +#include "DrawState.h" #include #include @@ -20,8 +21,8 @@ #include "LinkReceiver.h" #include "LinkSender.h" +#include "ServerProtocolStructs.h" -#include "DrawState.h" using std::nothrow; @@ -183,24 +184,24 @@ DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link) void DrawState::ReadFromLink(BPrivate::LinkReceiver& link) { - rgb_color highColor; - rgb_color lowColor; - pattern patt; + ViewSetStateInfo info; - link.Read(&fPenLocation); - link.Read(&fPenSize); - link.Read(&highColor, sizeof(rgb_color)); - link.Read(&lowColor, sizeof(rgb_color)); - link.Read(&patt, sizeof(pattern)); - link.Read((int8*)&fDrawingMode); - link.Read(&fOrigin); - link.Read((int8*)&fLineJoinMode); - link.Read((int8*)&fLineCapMode); - link.Read(&fMiterLimit); - link.Read((int8*)&fAlphaSrcMode); - link.Read((int8*)&fAlphaFncMode); - link.Read(&fScale); - link.Read(&fFontAliasing); + link.Read(&info); + + fPenLocation = info.penLocation; + fPenSize = info.penSize; + fHighColor = info.highColor; + fLowColor = info.lowColor; + fPattern = info.pattern; + fDrawingMode = info.drawingMode; + fOrigin = info.origin; + fScale = info.scale; + fLineJoinMode = info.lineJoin; + fLineCapMode = info.lineCap; + fMiterLimit = info.miterLimit; + fAlphaSrcMode = info.alphaSourceMode; + fAlphaFncMode = info.alphaFunctionMode; + fFontAliasing = info.fontAntialiasing; if (fPreviousState) { fCombinedOrigin = fPreviousState->fCombinedOrigin + fOrigin; @@ -210,11 +211,10 @@ DrawState::ReadFromLink(BPrivate::LinkReceiver& link) fCombinedScale = fScale; } - fHighColor = highColor; - fLowColor = lowColor; - fPattern = patt; // read clipping + // TODO: This could be optimized, but the user clipping regions are rarely + // used, so it's low priority... int32 clipRectCount; link.Read(&clipRectCount); @@ -237,33 +237,39 @@ void DrawState::WriteToLink(BPrivate::LinkSender& link) const { // Attach font state - link.Attach(fFont.GetFamilyAndStyle()); - link.Attach(fFont.Size()); - link.Attach(fFont.Shear()); - link.Attach(fFont.Rotation()); - link.Attach(fFont.FalseBoldWidth()); - link.Attach(fFont.Spacing()); - link.Attach(fFont.Encoding()); - link.Attach(fFont.Face()); - link.Attach(fFont.Flags()); + ViewGetStateInfo info; + info.fontID = fFont.GetFamilyAndStyle(); + info.fontSize = fFont.Size(); + info.fontShear = fFont.Shear(); + info.fontRotation = fFont.Rotation(); + info.fontFalseBoldWidth = fFont.FalseBoldWidth(); + info.fontSpacing = fFont.Spacing(); + info.fontEncoding = fFont.Encoding(); + info.fontFace = fFont.Face(); + info.fontFlags = fFont.Flags(); // Attach view state - link.Attach(fPenLocation); - link.Attach(fPenSize); - link.Attach(fHighColor); - link.Attach(fLowColor); - link.Attach(fPattern.GetInt64()); - link.Attach(fOrigin); - link.Attach((uint8)fDrawingMode); - link.Attach((uint8)fLineCapMode); - link.Attach((uint8)fLineJoinMode); - link.Attach(fMiterLimit); - link.Attach((uint8)fAlphaSrcMode); - link.Attach((uint8)fAlphaFncMode); - link.Attach(fScale); - link.Attach(fFontAliasing); + info.viewStateInfo.penLocation = fPenLocation; + info.viewStateInfo.penSize = fPenSize; + info.viewStateInfo.highColor = fHighColor; + info.viewStateInfo.lowColor = fLowColor; + info.viewStateInfo.pattern = (::pattern)fPattern.GetPattern(); + info.viewStateInfo.drawingMode = fDrawingMode; + info.viewStateInfo.origin = fOrigin; + info.viewStateInfo.scale = fScale; + info.viewStateInfo.lineJoin = fLineJoinMode; + info.viewStateInfo.lineCap = fLineCapMode; + info.viewStateInfo.miterLimit = fMiterLimit; + info.viewStateInfo.alphaSourceMode = fAlphaSrcMode; + info.viewStateInfo.alphaFunctionMode = fAlphaFncMode; + info.viewStateInfo.fontAntialiasing = fFontAliasing; + link.Attach(info); + + + // TODO: Could be optimized, but is low prio, since most views do not + // use a custom clipping region... if (fClippingRegion) { int32 clippingRectCount = fClippingRegion->CountRects(); link.Attach(clippingRectCount); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index e5437e73ed..7bd1352d20 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1545,17 +1546,15 @@ fDesktop->LockSingleWindow(); DTRACE(("ServerWindow %s: Message AS_VIEW_CURSOR: View: %s\n", Title(), fCurrentView->Name())); - int32 token; - bool sync; - link.Read(&token); - if (link.Read(&sync) != B_OK) + ViewSetViewCursorInfo info; + if (link.Read(&info) != B_OK) break; if (!fDesktop->GetCursorManager().Lock()) break; ServerCursor* cursor - = fDesktop->GetCursorManager().FindCursor(token); + = fDesktop->GetCursorManager().FindCursor(info.cursorToken); fCurrentView->SetCursor(cursor); fDesktop->GetCursorManager().Unlock(); @@ -1565,7 +1564,7 @@ fDesktop->LockSingleWindow(); if (fDesktop->ViewUnderMouse(fWindow) == fCurrentView->Token()) fServerApp->SetCurrentCursor(cursor); } - if (sync) { + if (info.sync) { // sync the client (it can now delete the cursor) fLink.StartMessage(B_OK); fLink.Flush(); @@ -1612,21 +1611,16 @@ fDesktop->LockSingleWindow(); { DTRACE(("ServerWindow %s: Message AS_VIEW_SET_LINE_MODE: " "View: %s\n", Title(), fCurrentView->Name())); - int8 lineCap, lineJoin; - float miterLimit; - - link.Read(&lineCap); - link.Read(&lineJoin); - if (link.Read(&miterLimit) != B_OK) + ViewSetLineModeInfo info; + if (link.Read(&info) != B_OK) break; - fCurrentView->CurrentState()->SetLineCapMode((cap_mode)lineCap); - fCurrentView->CurrentState()->SetLineJoinMode((join_mode)lineJoin); - fCurrentView->CurrentState()->SetMiterLimit(miterLimit); + fCurrentView->CurrentState()->SetLineCapMode(info.lineCap); + fCurrentView->CurrentState()->SetLineJoinMode(info.lineJoin); + fCurrentView->CurrentState()->SetMiterLimit(info.miterLimit); - fWindow->GetDrawingEngine()->SetStrokeMode((cap_mode)lineCap, - (join_mode)lineJoin, miterLimit); -// _UpdateDrawState(fCurrentView); + fWindow->GetDrawingEngine()->SetStrokeMode(info.lineCap, + info.lineJoin, info.miterLimit); break; } @@ -1634,10 +1628,13 @@ fDesktop->LockSingleWindow(); { DTRACE(("ServerWindow %s: Message AS_VIEW_GET_LINE_MODE: " "View: %s\n", Title(), fCurrentView->Name())); + ViewSetLineModeInfo info; + info.lineJoin = fCurrentView->CurrentState()->LineJoinMode(); + info.lineCap = fCurrentView->CurrentState()->LineCapMode(); + info.miterLimit = fCurrentView->CurrentState()->MiterLimit(); + fLink.StartMessage(B_OK); - fLink.Attach((int8)(fCurrentView->CurrentState()->LineCapMode())); - fLink.Attach((int8)(fCurrentView->CurrentState()->LineJoinMode())); - fLink.Attach(fCurrentView->CurrentState()->MiterLimit()); + fLink.Attach(info); fLink.Flush(); break; @@ -1690,16 +1687,15 @@ fDesktop->LockSingleWindow(); } case AS_VIEW_SET_PEN_LOC: { - float x, y; - link.Read(&x); - if (link.Read(&y) != B_OK) + BPoint location; + if (link.Read(&location) != B_OK) break; DTRACE(("ServerWindow %s: Message AS_VIEW_SET_PEN_LOC: " "View: %s -> BPoint(%.1f, %.1f)\n", Title(), - fCurrentView->Name(), x, y)); + fCurrentView->Name(), location.x, location.y)); - fCurrentView->CurrentState()->SetPenLocation(BPoint(x, y)); + fCurrentView->CurrentState()->SetPenLocation(location); break; } case AS_VIEW_GET_PEN_LOC: @@ -1847,27 +1843,28 @@ fDesktop->LockSingleWindow(); { DTRACE(("ServerWindow %s: Message AS_VIEW_SET_BLEND_MODE: " "View: %s\n", Title(), fCurrentView->Name())); - int8 srcAlpha, alphaFunc; - link.Read(&srcAlpha); - if (link.Read(&alphaFunc) != B_OK) + ViewBlendingModeInfo info; + if (link.Read(&info) != B_OK) break; fCurrentView->CurrentState()->SetBlendingMode( - (source_alpha)srcAlpha, (alpha_function)alphaFunc); + info.sourceAlpha, info.alphaFunction); fWindow->GetDrawingEngine()->SetBlendingMode( - (source_alpha)srcAlpha, (alpha_function)alphaFunc); + info.sourceAlpha, info.alphaFunction); break; } case AS_VIEW_GET_BLENDING_MODE: { DTRACE(("ServerWindow %s: Message AS_VIEW_GET_BLEND_MODE: " "View: %s\n", Title(), fCurrentView->Name())); + + ViewBlendingModeInfo info; + info.sourceAlpha = fCurrentView->CurrentState()->AlphaSrcMode(); + info.alphaFunction = fCurrentView->CurrentState()->AlphaFncMode(); + fLink.StartMessage(B_OK); - fLink.Attach((int8)( - fCurrentView->CurrentState()->AlphaSrcMode())); - fLink.Attach((int8)( - fCurrentView->CurrentState()->AlphaFncMode())); + fLink.Attach(info); fLink.Flush(); break; @@ -2286,27 +2283,23 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, switch (code) { case AS_STROKE_LINE: { - float x1, y1, x2, y2; - - link.Read(&x1); - link.Read(&y1); - link.Read(&x2); - if (link.Read(&y2) != B_OK) + ViewStrokeLineInfo info; + if (link.Read(&info) != B_OK) break; DTRACE(("ServerWindow %s: Message AS_STROKE_LINE: View: %s -> " "BPoint(%.1f, %.1f) - BPoint(%.1f, %.1f)\n", Title(), - fCurrentView->Name(), x1, y1, x2, y2)); + fCurrentView->Name(), + info.startPoint.x, info.startPoint.y, + info.endPoint.x, info.endPoint.y)); - BPoint p1(x1, y1); - BPoint p2(x2, y2); - BPoint penPos = p2; - fCurrentView->ConvertToScreenForDrawing(&p1); - fCurrentView->ConvertToScreenForDrawing(&p2); - drawingEngine->StrokeLine(p1, p2); + BPoint penPos = info.endPoint; + fCurrentView->ConvertToScreenForDrawing(&info.startPoint); + fCurrentView->ConvertToScreenForDrawing(&info.endPoint); + drawingEngine->StrokeLine(info.startPoint, info.endPoint); - // We update the pen here because many DrawingEngine calls which do not update the - // pen position actually call StrokeLine + // We update the pen here because many DrawingEngine calls which + // do not update the pen position actually call StrokeLine // TODO: Decide where to put this, for example, it cannot be done // for DrawString(), also there needs to be a decision, if penlocation @@ -2379,15 +2372,8 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, } case AS_VIEW_DRAW_BITMAP: { - int32 bitmapToken; - uint32 options; - BRect bitmapRect; - BRect viewRect; - - link.Read(&bitmapToken); - link.Read(&options); - link.Read(&viewRect); - if (link.Read(&bitmapRect) != B_OK) + ViewDrawBitmapInfo info; + if (link.Read(&info) != B_OK) break; #if 0 @@ -2395,23 +2381,24 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, options |= B_FILTER_BITMAP_BILINEAR; #endif - ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken); + ServerBitmap* bitmap = fServerApp->FindBitmap(info.bitmapToken); if (bitmap) { DTRACE(("ServerWindow %s: Message AS_VIEW_DRAW_BITMAP: " "View: %s, bitmap: %ld (size %ld x %ld), " "BRect(%.1f, %.1f, %.1f, %.1f) -> " "BRect(%.1f, %.1f, %.1f, %.1f)\n", - fTitle, fCurrentView->Name(), bitmapToken, + fTitle, fCurrentView->Name(), info.bitmapToken, bitmap->Width(), bitmap->Height(), - bitmapRect.left, bitmapRect.top, bitmapRect.right, - bitmapRect.bottom, viewRect.left, viewRect.top, - viewRect.right, viewRect.bottom)); + info.bitmapRect.left, info.bitmapRect.top, + info.bitmapRect.right, info.bitmapRect.bottom, + info.viewRect.left, info.viewRect.top, + info.viewRect.right, info.viewRect.bottom)); - fCurrentView->ConvertToScreenForDrawing(&viewRect); + fCurrentView->ConvertToScreenForDrawing(&info.viewRect); - drawingEngine->DrawBitmap(bitmap, bitmapRect, viewRect, - options); + drawingEngine->DrawBitmap(bitmap, info.bitmapRect, + info.viewRect, info.options); } break; @@ -2758,52 +2745,73 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, // 2) LineArrayData int32 lineCount; + if (link.Read(&lineCount) != B_OK || lineCount <= 0) + break; - link.Read(&lineCount); - if (lineCount > 0) { - LineArrayData lineData[lineCount]; + // To speed things up, try to use a stack allocation and only + // fall back to the heap if there are enough lines... + ViewLineArrayInfo* lineData; + static const int32 kStackBufferLineDataCount = 64; + ViewLineArrayInfo lineDataStackBuffer[kStackBufferLineDataCount]; + if (lineCount > kStackBufferLineDataCount) { + lineData = new(std::nothrow) ViewLineArrayInfo[lineCount]; + if (lineData == NULL) + break; + } else + lineData = lineDataStackBuffer; - for (int32 i = 0; i < lineCount; i++) { - LineArrayData* index = &lineData[i]; - - link.Read(&(index->pt1.x)); - link.Read(&(index->pt1.y)); - link.Read(&(index->pt2.x)); - link.Read(&(index->pt2.y)); - link.Read(&(index->color)); - - fCurrentView->ConvertToScreenForDrawing(&index->pt1); - fCurrentView->ConvertToScreenForDrawing(&index->pt2); - } - drawingEngine->StrokeLineArray(lineCount, lineData); + // Read them all in one go + size_t dataSize = lineCount * sizeof(ViewLineArrayInfo); + if (link.Read(lineData, dataSize) != B_OK) { + if (lineData != lineDataStackBuffer) + delete[] lineData; + break; } + + // Convert to screen coords and draw + for (int32 i = 0; i < lineCount; i++) { + ViewLineArrayInfo* index = &lineData[i]; + + fCurrentView->ConvertToScreenForDrawing(&index->startPoint); + fCurrentView->ConvertToScreenForDrawing(&index->endPoint); + } + drawingEngine->StrokeLineArray(lineCount, lineData); + + if (lineData != lineDataStackBuffer) + delete[] lineData; break; } case AS_DRAW_STRING: case AS_DRAW_STRING_WITH_DELTA: { - char* string; - int32 length; - BPoint location; - escapement_delta _delta; - escapement_delta* delta = NULL; - - link.Read(&length); - link.Read(&location); - if (code == AS_DRAW_STRING_WITH_DELTA) { - link.Read(&_delta); - if (_delta.nonspace != 0.0 || _delta.space != 0.0) - delta = &_delta; - } - if (link.ReadString(&string) != B_OK) + ViewDrawStringInfo info; + if (link.Read(&info) != B_OK) break; + char* string = (char*)malloc(info.stringLength + 1); + if (string == NULL) + break; + + escapement_delta* delta = NULL; + if (code == AS_DRAW_STRING_WITH_DELTA) { + // In this case, info.delta will contain valid values. + delta = &info.delta; + } + + if (link.Read(string, info.stringLength) != B_OK) { + free(string); + break; + } + // Terminate the string, if nothing else, it's important + // for the DTRACE call below... + string[info.stringLength] = '\0'; + DTRACE(("ServerWindow %s: Message AS_DRAW_STRING, View: %s " "-> %s\n", Title(), fCurrentView->Name(), string)); - fCurrentView->ConvertToScreenForDrawing(&location); - BPoint penLocation = drawingEngine->DrawString(string, length, - location, delta); + fCurrentView->ConvertToScreenForDrawing(&info.location); + BPoint penLocation = drawingEngine->DrawString(string, + info.stringLength, info.location, delta); fCurrentView->ConvertFromScreenForDrawing(&penLocation); fCurrentView->CurrentState()->SetPenLocation(penLocation); @@ -2903,12 +2911,11 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) case AS_VIEW_SET_PEN_LOC: { - float x, y; - link.Read(&x); - link.Read(&y); - picture->WriteSetPenLocation(BPoint(x, y)); + BPoint location; + link.Read(&location); + picture->WriteSetPenLocation(location); - fCurrentView->CurrentState()->SetPenLocation(BPoint(x, y)); + fCurrentView->CurrentState()->SetPenLocation(location); break; } case AS_VIEW_SET_PEN_SIZE: @@ -2925,21 +2932,19 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) case AS_VIEW_SET_LINE_MODE: { - int8 lineCap, lineJoin; - float miterLimit; - link.Read(&lineCap); - link.Read(&lineJoin); - link.Read(&miterLimit); + ViewSetLineModeInfo info; + link.Read(&info); - picture->WriteSetLineMode((cap_mode)lineCap, (join_mode)lineJoin, miterLimit); + picture->WriteSetLineMode(info.lineCap, info.lineJoin, + info.miterLimit); - fCurrentView->CurrentState()->SetLineCapMode((cap_mode)lineCap); - fCurrentView->CurrentState()->SetLineJoinMode((join_mode)lineJoin); - fCurrentView->CurrentState()->SetMiterLimit(miterLimit); + fCurrentView->CurrentState()->SetLineCapMode(info.lineCap); + fCurrentView->CurrentState()->SetLineJoinMode(info.lineJoin); + fCurrentView->CurrentState()->SetMiterLimit(info.miterLimit); - fWindow->GetDrawingEngine()->SetStrokeMode((cap_mode)lineCap, - (join_mode)lineJoin, miterLimit); + fWindow->GetDrawingEngine()->SetStrokeMode(info.lineCap, + info.lineJoin, info.miterLimit); break; } case AS_VIEW_SET_SCALE: @@ -3081,14 +3086,10 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) case AS_STROKE_LINE: { - float x1, y1, x2, y2; + ViewStrokeLineInfo info; + link.Read(&info); - link.Read(&x1); - link.Read(&y1); - link.Read(&x2); - link.Read(&y2); - - picture->WriteStrokeLine(BPoint(x1, y1), BPoint(x2, y2)); + picture->WriteStrokeLine(info.startPoint, info.endPoint); break; } @@ -3102,17 +3103,13 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) picture->WritePushState(); for (int32 i = 0; i < lineCount; i++) { - float x1, y1, x2, y2; - link.Read(&x1); - link.Read(&y1); - link.Read(&x2); - link.Read(&y2); + ViewLineArrayInfo lineData; + if (link.Read(&lineData) != B_OK) + break; - rgb_color color; - link.Read(&color); - - picture->WriteSetHighColor(color); - picture->WriteStrokeLine(BPoint(x1, y1), BPoint(x2, y2)); + picture->WriteSetHighColor(lineData.color); + picture->WriteStrokeLine(lineData.startPoint, + lineData.endPoint); } picture->WritePopState(); @@ -3139,18 +3136,29 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) case AS_DRAW_STRING: case AS_DRAW_STRING_WITH_DELTA: { - char* string = NULL; - int32 length; - BPoint location; + ViewDrawStringInfo info; + if (link.Read(&info) != B_OK) + break; - link.Read(&length); - link.Read(&location); - escapement_delta delta = { 0, 0 }; - if (code == AS_DRAW_STRING_WITH_DELTA) - link.Read(&delta); - link.ReadString(&string); + char* string = (char*)malloc(info.stringLength + 1); + if (string == NULL) + break; - picture->WriteDrawString(location, string, length, delta); + if (code != AS_DRAW_STRING_WITH_DELTA) { + // In this case, info.delta will NOT contain valid values. + info.delta = (escapement_delta){ 0, 0 }; + } + + if (link.Read(string, info.stringLength) != B_OK) { + free(string); + break; + } + // Terminate the string, if nothing else, it's important + // for the DTRACE call below... + string[info.stringLength] = '\0'; + + picture->WriteDrawString(info.location, string, info.stringLength, + info.delta); free(string); break; @@ -3190,25 +3198,17 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) case AS_VIEW_DRAW_BITMAP: { - int32 token; - link.Read(&token); + ViewDrawBitmapInfo info; + link.Read(&info); - uint32 options; - link.Read(&options); - - BRect viewRect; - link.Read(&viewRect); - - BRect bitmapRect; - link.Read(&bitmapRect); - - ServerBitmap *bitmap = App()->FindBitmap(token); + ServerBitmap *bitmap = App()->FindBitmap(info.bitmapToken); if (bitmap == NULL) break; - picture->WriteDrawBitmap(bitmapRect, viewRect, bitmap->Width(), - bitmap->Height(), bitmap->BytesPerRow(), bitmap->ColorSpace(), - options, bitmap->Bits(), bitmap->BitsLength()); + picture->WriteDrawBitmap(info.bitmapRect, info.viewRect, + bitmap->Width(), bitmap->Height(), bitmap->BytesPerRow(), + bitmap->ColorSpace(), info.options, bitmap->Bits(), + bitmap->BitsLength()); break; } @@ -3293,20 +3293,18 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) /* case AS_VIEW_SET_BLENDING_MODE: { - int8 srcAlpha, alphaFunc; - - link.Read(&srcAlpha); - link.Read(&alphaFunc); + ViewBlendingModeInfo info; + link.Read(&info); picture->BeginOp(B_PIC_SET_BLENDING_MODE); - picture->AddInt16((int16)srcAlpha); - picture->AddInt16((int16)alphaFunc); + picture->AddInt16((int16)info.sourceAlpha); + picture->AddInt16((int16)info.alphaFunction); picture->EndOp(); - fCurrentView->CurrentState()->SetBlendingMode((source_alpha)srcAlpha, - (alpha_function)alphaFunc); - fWindow->GetDrawingEngine()->SetBlendingMode((source_alpha)srcAlpha, - (alpha_function)alphaFunc); + fCurrentView->CurrentState()->SetBlendingMode(info.sourceAlpha, + info.alphaFunction); + fWindow->GetDrawingEngine()->SetBlendingMode(info.sourceAlpha, + info.alphaFunction); break; }*/ default: diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index 8d88b4323a..624b1ceae3 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -1207,26 +1207,26 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end) // StrokeLineArray void DrawingEngine::StrokeLineArray(int32 numLines, - const LineArrayData *linedata) + const ViewLineArrayInfo *lineData) { CRASH_IF_NOT_LOCKED - if (!linedata || numLines <= 0) + if (!lineData || numLines <= 0) return; // figure out bounding box for line array - const LineArrayData *data = (const LineArrayData *)&(linedata[0]); - BRect touched(min_c(data->pt1.x, data->pt2.x), - min_c(data->pt1.y, data->pt2.y), - max_c(data->pt1.x, data->pt2.x), - max_c(data->pt1.y, data->pt2.y)); + const ViewLineArrayInfo* data = (const ViewLineArrayInfo*)&(lineData[0]); + BRect touched(min_c(data->startPoint.x, data->endPoint.x), + min_c(data->startPoint.y, data->endPoint.y), + max_c(data->startPoint.x, data->endPoint.x), + max_c(data->startPoint.y, data->endPoint.y)); for (int32 i = 1; i < numLines; i++) { - data = (const LineArrayData *)&(linedata[i]); - BRect box(min_c(data->pt1.x, data->pt2.x), - min_c(data->pt1.y, data->pt2.y), - max_c(data->pt1.x, data->pt2.x), - max_c(data->pt1.y, data->pt2.y)); + data = (const ViewLineArrayInfo*)&(lineData[i]); + BRect box(min_c(data->startPoint.x, data->endPoint.x), + min_c(data->startPoint.y, data->endPoint.y), + max_c(data->startPoint.x, data->endPoint.x), + max_c(data->startPoint.y, data->endPoint.y)); touched = touched | box; } extend_by_stroke_width(touched, fPainter->PenSize()); @@ -1234,7 +1234,7 @@ DrawingEngine::StrokeLineArray(int32 numLines, if (touched.IsValid()) { AutoFloatingOverlaysHider _(fGraphicsCard, touched); - data = (const LineArrayData *)&(linedata[0]); + data = (const ViewLineArrayInfo*)&(lineData[0]); // store current graphics state, we mess with the // high color and pattern... @@ -1243,12 +1243,12 @@ DrawingEngine::StrokeLineArray(int32 numLines, fPainter->SetHighColor(data->color); fPainter->SetPattern(B_SOLID_HIGH); - fPainter->StrokeLine(data->pt1, data->pt2); + fPainter->StrokeLine(data->startPoint, data->endPoint); for (int32 i = 1; i < numLines; i++) { - data = (const LineArrayData *)&(linedata[i]); + data = (const ViewLineArrayInfo*)&(lineData[i]); fPainter->SetHighColor(data->color); - fPainter->StrokeLine(data->pt1, data->pt2); + fPainter->StrokeLine(data->startPoint, data->endPoint); } // restore correct drawing state highcolor and pattern diff --git a/src/servers/app/drawing/DrawingEngine.h b/src/servers/app/drawing/DrawingEngine.h index ccbc98d138..e97c4c8794 100644 --- a/src/servers/app/drawing/DrawingEngine.h +++ b/src/servers/app/drawing/DrawingEngine.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "HWInterface.h" @@ -29,11 +30,6 @@ class ServerBitmap; class ServerCursor; class ServerFont; -typedef struct { - BPoint pt1; - BPoint pt2; - rgb_color color; -} LineArrayData; class DrawingEngine : public HWInterfaceListener { public: @@ -158,7 +154,7 @@ public: const BPoint& end); void StrokeLineArray(int32 numlines, - const LineArrayData* data); + const ViewLineArrayInfo* data); // -------- text related calls diff --git a/src/servers/app/drawing/PatternHandler.h b/src/servers/app/drawing/PatternHandler.h index 55bf1348f1..1dd77a9547 100644 --- a/src/servers/app/drawing/PatternHandler.h +++ b/src/servers/app/drawing/PatternHandler.h @@ -20,7 +20,7 @@ class BPoint; class Pattern { public: - Pattern(void) {} + Pattern() {} Pattern(const uint64& p) { fPattern.type64 = p; } @@ -34,12 +34,15 @@ class Pattern { Pattern(const pattern& src) { fPattern.type64 = *(uint64*)src.data; } - inline const int8* GetInt8(void) const + inline const int8* GetInt8() const { return fPattern.type8; } - inline uint64 GetInt64(void) const + inline uint64 GetInt64() const { return fPattern.type64; } + inline const ::pattern& GetPattern() const + { return *(const ::pattern*)&fPattern.type64; } + inline void Set(const int8* p) { fPattern.type64 = *((const uint64*)p); }