1dcaec19cSAlexander von Gluck IV /* 2dcaec19cSAlexander von Gluck IV * Copyright 2009-2010, Haiku, Inc. 3dcaec19cSAlexander von Gluck IV * Distributed under the terms of the MIT License. 4dcaec19cSAlexander von Gluck IV * 5dcaec19cSAlexander von Gluck IV * Authors: 6dcaec19cSAlexander von Gluck IV * Michael Lotz <mmlr@mlotz.ch> 7dcaec19cSAlexander von Gluck IV */ 8dcaec19cSAlexander von Gluck IV 9dcaec19cSAlexander von Gluck IV #include "RemoteDrawingEngine.h" 10dcaec19cSAlexander von Gluck IV #include "RemoteMessage.h" 11dcaec19cSAlexander von Gluck IV 12dcaec19cSAlexander von Gluck IV #include "BitmapDrawingEngine.h" 13dcaec19cSAlexander von Gluck IV #include "DrawState.h" 145ed41cffSMichael Lotz #include "ServerTokenSpace.h" 15dcaec19cSAlexander von Gluck IV 16dcaec19cSAlexander von Gluck IV #include <Bitmap.h> 17dcaec19cSAlexander von Gluck IV #include <utf8_functions.h> 18dcaec19cSAlexander von Gluck IV 19dcaec19cSAlexander von Gluck IV #include <new> 20dcaec19cSAlexander von Gluck IV 21dcaec19cSAlexander von Gluck IV 225ed41cffSMichael Lotz #define TRACE(x...) /*debug_printf("RemoteDrawingEngine: " x)*/ 235ed41cffSMichael Lotz #define TRACE_ALWAYS(x...) debug_printf("RemoteDrawingEngine: " x) 245ed41cffSMichael Lotz #define TRACE_ERROR(x...) debug_printf("RemoteDrawingEngine: " x) 255ed41cffSMichael Lotz 265ed41cffSMichael Lotz 27dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::RemoteDrawingEngine(RemoteHWInterface* interface) 28dcaec19cSAlexander von Gluck IV : 29dcaec19cSAlexander von Gluck IV DrawingEngine(interface), 30dcaec19cSAlexander von Gluck IV fHWInterface(interface), 315ed41cffSMichael Lotz fToken(gTokenSpace.NewToken(kRemoteDrawingEngineToken, this)), 32dcaec19cSAlexander von Gluck IV fExtendWidth(0), 33dcaec19cSAlexander von Gluck IV fCallbackAdded(false), 34dcaec19cSAlexander von Gluck IV fResultNotify(-1), 35dcaec19cSAlexander von Gluck IV fStringWidthResult(0.0f), 36dcaec19cSAlexander von Gluck IV fReadBitmapResult(NULL), 37dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine(NULL) 38dcaec19cSAlexander von Gluck IV { 39dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 40dcaec19cSAlexander von Gluck IV message.Start(RP_CREATE_STATE); 41dcaec19cSAlexander von Gluck IV message.Add(fToken); 42dcaec19cSAlexander von Gluck IV } 43dcaec19cSAlexander von Gluck IV 44dcaec19cSAlexander von Gluck IV 45dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::~RemoteDrawingEngine() 46dcaec19cSAlexander von Gluck IV { 47dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 48dcaec19cSAlexander von Gluck IV message.Start(RP_DELETE_STATE); 49dcaec19cSAlexander von Gluck IV message.Add(fToken); 50dcaec19cSAlexander von Gluck IV message.Flush(); 51dcaec19cSAlexander von Gluck IV 52dcaec19cSAlexander von Gluck IV delete fBitmapDrawingEngine; 53dcaec19cSAlexander von Gluck IV 54dcaec19cSAlexander von Gluck IV if (fCallbackAdded) 55dcaec19cSAlexander von Gluck IV fHWInterface->RemoveCallback(fToken); 56dcaec19cSAlexander von Gluck IV if (fResultNotify >= 0) 57dcaec19cSAlexander von Gluck IV delete_sem(fResultNotify); 58dcaec19cSAlexander von Gluck IV } 59dcaec19cSAlexander von Gluck IV 60dcaec19cSAlexander von Gluck IV 61dcaec19cSAlexander von Gluck IV // #pragma mark - 62dcaec19cSAlexander von Gluck IV 63dcaec19cSAlexander von Gluck IV 64dcaec19cSAlexander von Gluck IV void 65dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FrameBufferChanged() 66dcaec19cSAlexander von Gluck IV { 67dcaec19cSAlexander von Gluck IV // Not allowed 68dcaec19cSAlexander von Gluck IV } 69dcaec19cSAlexander von Gluck IV 70dcaec19cSAlexander von Gluck IV 71dcaec19cSAlexander von Gluck IV // #pragma mark - 72dcaec19cSAlexander von Gluck IV 73dcaec19cSAlexander von Gluck IV 74dcaec19cSAlexander von Gluck IV void 75dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetCopyToFrontEnabled(bool enabled) 76dcaec19cSAlexander von Gluck IV { 77dcaec19cSAlexander von Gluck IV DrawingEngine::SetCopyToFrontEnabled(enabled); 78dcaec19cSAlexander von Gluck IV 79dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 80dcaec19cSAlexander von Gluck IV message.Start(enabled ? RP_ENABLE_SYNC_DRAWING : RP_DISABLE_SYNC_DRAWING); 81dcaec19cSAlexander von Gluck IV message.Add(fToken); 82dcaec19cSAlexander von Gluck IV } 83dcaec19cSAlexander von Gluck IV 84dcaec19cSAlexander von Gluck IV 85dcaec19cSAlexander von Gluck IV // #pragma mark - 86dcaec19cSAlexander von Gluck IV 87dcaec19cSAlexander von Gluck IV 88dcaec19cSAlexander von Gluck IV //! the RemoteDrawingEngine needs to be locked! 89dcaec19cSAlexander von Gluck IV void 90dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::ConstrainClippingRegion(const BRegion* region) 91dcaec19cSAlexander von Gluck IV { 92dcaec19cSAlexander von Gluck IV if (fClippingRegion == *region) 93dcaec19cSAlexander von Gluck IV return; 94dcaec19cSAlexander von Gluck IV 95dcaec19cSAlexander von Gluck IV fClippingRegion = *region; 96dcaec19cSAlexander von Gluck IV 97dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 98dcaec19cSAlexander von Gluck IV message.Start(RP_CONSTRAIN_CLIPPING_REGION); 99dcaec19cSAlexander von Gluck IV message.Add(fToken); 100dcaec19cSAlexander von Gluck IV message.AddRegion(*region); 101dcaec19cSAlexander von Gluck IV } 102dcaec19cSAlexander von Gluck IV 103dcaec19cSAlexander von Gluck IV 104dcaec19cSAlexander von Gluck IV void 105dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetDrawState(const DrawState* state, int32 xOffset, 106dcaec19cSAlexander von Gluck IV int32 yOffset) 107dcaec19cSAlexander von Gluck IV { 108dcaec19cSAlexander von Gluck IV SetPenSize(state->PenSize()); 109dcaec19cSAlexander von Gluck IV SetDrawingMode(state->GetDrawingMode()); 110dcaec19cSAlexander von Gluck IV SetBlendingMode(state->AlphaSrcMode(), state->AlphaFncMode()); 111dcaec19cSAlexander von Gluck IV SetPattern(state->GetPattern().GetPattern()); 112dcaec19cSAlexander von Gluck IV SetStrokeMode(state->LineCapMode(), state->LineJoinMode(), 113dcaec19cSAlexander von Gluck IV state->MiterLimit()); 114dcaec19cSAlexander von Gluck IV SetHighColor(state->HighColor()); 115dcaec19cSAlexander von Gluck IV SetLowColor(state->LowColor()); 116dcaec19cSAlexander von Gluck IV SetFont(state->Font()); 11791c1d3dbSMichael Lotz SetTransform(state->CombinedTransform()); 118dcaec19cSAlexander von Gluck IV 119dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 120dcaec19cSAlexander von Gluck IV message.Start(RP_SET_OFFSETS); 121dcaec19cSAlexander von Gluck IV message.Add(fToken); 122dcaec19cSAlexander von Gluck IV message.Add(xOffset); 123dcaec19cSAlexander von Gluck IV message.Add(yOffset); 124dcaec19cSAlexander von Gluck IV } 125dcaec19cSAlexander von Gluck IV 126dcaec19cSAlexander von Gluck IV 127dcaec19cSAlexander von Gluck IV void 128dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetHighColor(const rgb_color& color) 129dcaec19cSAlexander von Gluck IV { 130dcaec19cSAlexander von Gluck IV if (fState.HighColor() == color) 131dcaec19cSAlexander von Gluck IV return; 132dcaec19cSAlexander von Gluck IV 133dcaec19cSAlexander von Gluck IV fState.SetHighColor(color); 134dcaec19cSAlexander von Gluck IV 135dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 136dcaec19cSAlexander von Gluck IV message.Start(RP_SET_HIGH_COLOR); 137dcaec19cSAlexander von Gluck IV message.Add(fToken); 138dcaec19cSAlexander von Gluck IV message.Add(color); 139dcaec19cSAlexander von Gluck IV } 140dcaec19cSAlexander von Gluck IV 141dcaec19cSAlexander von Gluck IV 142dcaec19cSAlexander von Gluck IV void 143dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetLowColor(const rgb_color& color) 144dcaec19cSAlexander von Gluck IV { 145dcaec19cSAlexander von Gluck IV if (fState.LowColor() == color) 146dcaec19cSAlexander von Gluck IV return; 147dcaec19cSAlexander von Gluck IV 148dcaec19cSAlexander von Gluck IV fState.SetLowColor(color); 149dcaec19cSAlexander von Gluck IV 150dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 151dcaec19cSAlexander von Gluck IV message.Start(RP_SET_LOW_COLOR); 152dcaec19cSAlexander von Gluck IV message.Add(fToken); 153dcaec19cSAlexander von Gluck IV message.Add(color); 154dcaec19cSAlexander von Gluck IV } 155dcaec19cSAlexander von Gluck IV 156dcaec19cSAlexander von Gluck IV 157dcaec19cSAlexander von Gluck IV void 158dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetPenSize(float size) 159dcaec19cSAlexander von Gluck IV { 160dcaec19cSAlexander von Gluck IV if (fState.PenSize() == size) 161dcaec19cSAlexander von Gluck IV return; 162dcaec19cSAlexander von Gluck IV 163dcaec19cSAlexander von Gluck IV fState.SetPenSize(size); 164dcaec19cSAlexander von Gluck IV fExtendWidth = -(size / 2); 165dcaec19cSAlexander von Gluck IV 166dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 167dcaec19cSAlexander von Gluck IV message.Start(RP_SET_PEN_SIZE); 168dcaec19cSAlexander von Gluck IV message.Add(fToken); 169dcaec19cSAlexander von Gluck IV message.Add(size); 170dcaec19cSAlexander von Gluck IV } 171dcaec19cSAlexander von Gluck IV 172dcaec19cSAlexander von Gluck IV 173dcaec19cSAlexander von Gluck IV void 174dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetStrokeMode(cap_mode lineCap, join_mode joinMode, 175dcaec19cSAlexander von Gluck IV float miterLimit) 176dcaec19cSAlexander von Gluck IV { 177dcaec19cSAlexander von Gluck IV if (fState.LineCapMode() == lineCap && fState.LineJoinMode() == joinMode 178dcaec19cSAlexander von Gluck IV && fState.MiterLimit() == miterLimit) 179dcaec19cSAlexander von Gluck IV return; 180dcaec19cSAlexander von Gluck IV 181dcaec19cSAlexander von Gluck IV fState.SetLineCapMode(lineCap); 182dcaec19cSAlexander von Gluck IV fState.SetLineJoinMode(joinMode); 183dcaec19cSAlexander von Gluck IV fState.SetMiterLimit(miterLimit); 184dcaec19cSAlexander von Gluck IV 185dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 186dcaec19cSAlexander von Gluck IV message.Start(RP_SET_STROKE_MODE); 187dcaec19cSAlexander von Gluck IV message.Add(fToken); 188dcaec19cSAlexander von Gluck IV message.Add(lineCap); 189dcaec19cSAlexander von Gluck IV message.Add(joinMode); 190dcaec19cSAlexander von Gluck IV message.Add(miterLimit); 191dcaec19cSAlexander von Gluck IV } 192dcaec19cSAlexander von Gluck IV 193dcaec19cSAlexander von Gluck IV 194dcaec19cSAlexander von Gluck IV void 195dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetBlendingMode(source_alpha sourceAlpha, 196dcaec19cSAlexander von Gluck IV alpha_function alphaFunc) 197dcaec19cSAlexander von Gluck IV { 198dcaec19cSAlexander von Gluck IV if (fState.AlphaSrcMode() == sourceAlpha 199dcaec19cSAlexander von Gluck IV && fState.AlphaFncMode() == alphaFunc) 200dcaec19cSAlexander von Gluck IV return; 201dcaec19cSAlexander von Gluck IV 202dcaec19cSAlexander von Gluck IV fState.SetBlendingMode(sourceAlpha, alphaFunc); 203dcaec19cSAlexander von Gluck IV 204dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 205dcaec19cSAlexander von Gluck IV message.Start(RP_SET_BLENDING_MODE); 206dcaec19cSAlexander von Gluck IV message.Add(fToken); 207dcaec19cSAlexander von Gluck IV message.Add(sourceAlpha); 208dcaec19cSAlexander von Gluck IV message.Add(alphaFunc); 209dcaec19cSAlexander von Gluck IV } 210dcaec19cSAlexander von Gluck IV 211dcaec19cSAlexander von Gluck IV 212dcaec19cSAlexander von Gluck IV void 213dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetPattern(const struct pattern& pattern) 214dcaec19cSAlexander von Gluck IV { 215dcaec19cSAlexander von Gluck IV if (fState.GetPattern() == pattern) 216dcaec19cSAlexander von Gluck IV return; 217dcaec19cSAlexander von Gluck IV 218dcaec19cSAlexander von Gluck IV fState.SetPattern(pattern); 219dcaec19cSAlexander von Gluck IV 220dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 221dcaec19cSAlexander von Gluck IV message.Start(RP_SET_PATTERN); 222dcaec19cSAlexander von Gluck IV message.Add(fToken); 223dcaec19cSAlexander von Gluck IV message.Add(pattern); 224dcaec19cSAlexander von Gluck IV } 225dcaec19cSAlexander von Gluck IV 226dcaec19cSAlexander von Gluck IV 227dcaec19cSAlexander von Gluck IV void 228dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetDrawingMode(drawing_mode mode) 229dcaec19cSAlexander von Gluck IV { 230dcaec19cSAlexander von Gluck IV if (fState.GetDrawingMode() == mode) 231dcaec19cSAlexander von Gluck IV return; 232dcaec19cSAlexander von Gluck IV 233dcaec19cSAlexander von Gluck IV fState.SetDrawingMode(mode); 234dcaec19cSAlexander von Gluck IV 235dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 236dcaec19cSAlexander von Gluck IV message.Start(RP_SET_DRAWING_MODE); 237dcaec19cSAlexander von Gluck IV message.Add(fToken); 238dcaec19cSAlexander von Gluck IV message.Add(mode); 239dcaec19cSAlexander von Gluck IV } 240dcaec19cSAlexander von Gluck IV 241dcaec19cSAlexander von Gluck IV 242dcaec19cSAlexander von Gluck IV void 243dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetDrawingMode(drawing_mode mode, drawing_mode& oldMode) 244dcaec19cSAlexander von Gluck IV { 245dcaec19cSAlexander von Gluck IV oldMode = fState.GetDrawingMode(); 246dcaec19cSAlexander von Gluck IV SetDrawingMode(mode); 247dcaec19cSAlexander von Gluck IV } 248dcaec19cSAlexander von Gluck IV 249dcaec19cSAlexander von Gluck IV 250dcaec19cSAlexander von Gluck IV void 251dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetFont(const ServerFont& font) 252dcaec19cSAlexander von Gluck IV { 253dcaec19cSAlexander von Gluck IV if (fState.Font() == font) 254dcaec19cSAlexander von Gluck IV return; 255dcaec19cSAlexander von Gluck IV 256dcaec19cSAlexander von Gluck IV fState.SetFont(font); 257dcaec19cSAlexander von Gluck IV 258dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 259dcaec19cSAlexander von Gluck IV message.Start(RP_SET_FONT); 260dcaec19cSAlexander von Gluck IV message.Add(fToken); 261dcaec19cSAlexander von Gluck IV message.AddFont(font); 262dcaec19cSAlexander von Gluck IV } 263dcaec19cSAlexander von Gluck IV 264dcaec19cSAlexander von Gluck IV 265dcaec19cSAlexander von Gluck IV void 266dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::SetFont(const DrawState* state) 267dcaec19cSAlexander von Gluck IV { 268dcaec19cSAlexander von Gluck IV SetFont(state->Font()); 269dcaec19cSAlexander von Gluck IV } 270dcaec19cSAlexander von Gluck IV 271dcaec19cSAlexander von Gluck IV 27291c1d3dbSMichael Lotz void 27391c1d3dbSMichael Lotz RemoteDrawingEngine::SetTransform(const BAffineTransform& transform) 27491c1d3dbSMichael Lotz { 27591c1d3dbSMichael Lotz if (fState.Transform() == transform) 27691c1d3dbSMichael Lotz return; 27791c1d3dbSMichael Lotz 27891c1d3dbSMichael Lotz fState.SetTransform(transform); 27991c1d3dbSMichael Lotz 28091c1d3dbSMichael Lotz RemoteMessage message(NULL, fHWInterface->SendBuffer()); 28191c1d3dbSMichael Lotz message.Start(RP_SET_TRANSFORM); 28291c1d3dbSMichael Lotz message.Add(fToken); 28391c1d3dbSMichael Lotz message.AddTransform(transform); 28491c1d3dbSMichael Lotz } 28591c1d3dbSMichael Lotz 28691c1d3dbSMichael Lotz 287dcaec19cSAlexander von Gluck IV // #pragma mark - 288dcaec19cSAlexander von Gluck IV 289dcaec19cSAlexander von Gluck IV 290dcaec19cSAlexander von Gluck IV BRect 291dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::CopyRect(BRect rect, int32 xOffset, int32 yOffset) const 292dcaec19cSAlexander von Gluck IV { 293dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 294dcaec19cSAlexander von Gluck IV message.Start(RP_COPY_RECT_NO_CLIPPING); 295dcaec19cSAlexander von Gluck IV message.Add(xOffset); 296dcaec19cSAlexander von Gluck IV message.Add(yOffset); 297dcaec19cSAlexander von Gluck IV message.Add(rect); 298dcaec19cSAlexander von Gluck IV return rect.OffsetBySelf(xOffset, yOffset); 299dcaec19cSAlexander von Gluck IV } 300dcaec19cSAlexander von Gluck IV 301dcaec19cSAlexander von Gluck IV 302dcaec19cSAlexander von Gluck IV void 303dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::InvertRect(BRect rect) 304dcaec19cSAlexander von Gluck IV { 305dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 306dcaec19cSAlexander von Gluck IV return; 307dcaec19cSAlexander von Gluck IV 308dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 309dcaec19cSAlexander von Gluck IV message.Start(RP_INVERT_RECT); 310dcaec19cSAlexander von Gluck IV message.Add(fToken); 311dcaec19cSAlexander von Gluck IV message.Add(rect); 312dcaec19cSAlexander von Gluck IV } 313dcaec19cSAlexander von Gluck IV 314dcaec19cSAlexander von Gluck IV 315dcaec19cSAlexander von Gluck IV void 316dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawBitmap(ServerBitmap* bitmap, const BRect& _bitmapRect, 317dcaec19cSAlexander von Gluck IV const BRect& _viewRect, uint32 options) 318dcaec19cSAlexander von Gluck IV { 319dcaec19cSAlexander von Gluck IV BRect bitmapRect = _bitmapRect; 320dcaec19cSAlexander von Gluck IV BRect viewRect = _viewRect; 321dcaec19cSAlexander von Gluck IV double xScale = (bitmapRect.Width() + 1) / (viewRect.Width() + 1); 322dcaec19cSAlexander von Gluck IV double yScale = (bitmapRect.Height() + 1) / (viewRect.Height() + 1); 323dcaec19cSAlexander von Gluck IV 324dcaec19cSAlexander von Gluck IV // constrain rect to passed bitmap bounds 325dcaec19cSAlexander von Gluck IV // and transfer the changes to the viewRect with the right scale 326dcaec19cSAlexander von Gluck IV BRect actualBitmapRect = bitmap->Bounds(); 327dcaec19cSAlexander von Gluck IV if (bitmapRect.left < actualBitmapRect.left) { 328dcaec19cSAlexander von Gluck IV float diff = actualBitmapRect.left - bitmapRect.left; 329dcaec19cSAlexander von Gluck IV viewRect.left += diff / xScale; 330dcaec19cSAlexander von Gluck IV bitmapRect.left = actualBitmapRect.left; 331dcaec19cSAlexander von Gluck IV } 332dcaec19cSAlexander von Gluck IV if (bitmapRect.top < actualBitmapRect.top) { 333dcaec19cSAlexander von Gluck IV float diff = actualBitmapRect.top - bitmapRect.top; 334dcaec19cSAlexander von Gluck IV viewRect.top += diff / yScale; 335dcaec19cSAlexander von Gluck IV bitmapRect.top = actualBitmapRect.top; 336dcaec19cSAlexander von Gluck IV } 337dcaec19cSAlexander von Gluck IV if (bitmapRect.right > actualBitmapRect.right) { 338dcaec19cSAlexander von Gluck IV float diff = bitmapRect.right - actualBitmapRect.right; 339dcaec19cSAlexander von Gluck IV viewRect.right -= diff / xScale; 340dcaec19cSAlexander von Gluck IV bitmapRect.right = actualBitmapRect.right; 341dcaec19cSAlexander von Gluck IV } 342dcaec19cSAlexander von Gluck IV if (bitmapRect.bottom > actualBitmapRect.bottom) { 343dcaec19cSAlexander von Gluck IV float diff = bitmapRect.bottom - actualBitmapRect.bottom; 344dcaec19cSAlexander von Gluck IV viewRect.bottom -= diff / yScale; 345dcaec19cSAlexander von Gluck IV bitmapRect.bottom = actualBitmapRect.bottom; 346dcaec19cSAlexander von Gluck IV } 347dcaec19cSAlexander von Gluck IV 348dcaec19cSAlexander von Gluck IV BRegion clippedRegion(viewRect); 349dcaec19cSAlexander von Gluck IV clippedRegion.IntersectWith(&fClippingRegion); 350dcaec19cSAlexander von Gluck IV 351dcaec19cSAlexander von Gluck IV int32 rectCount = clippedRegion.CountRects(); 352dcaec19cSAlexander von Gluck IV if (rectCount == 0) 353dcaec19cSAlexander von Gluck IV return; 354dcaec19cSAlexander von Gluck IV 355dcaec19cSAlexander von Gluck IV if (rectCount > 1 || (rectCount == 1 && clippedRegion.RectAt(0) != viewRect) 356dcaec19cSAlexander von Gluck IV || viewRect.Width() < bitmapRect.Width() 357dcaec19cSAlexander von Gluck IV || viewRect.Height() < bitmapRect.Height()) { 358dcaec19cSAlexander von Gluck IV UtilityBitmap** bitmaps; 359dcaec19cSAlexander von Gluck IV if (_ExtractBitmapRegions(*bitmap, options, bitmapRect, viewRect, 360dcaec19cSAlexander von Gluck IV xScale, yScale, clippedRegion, bitmaps) != B_OK) { 361dcaec19cSAlexander von Gluck IV return; 362dcaec19cSAlexander von Gluck IV } 363dcaec19cSAlexander von Gluck IV 364dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 365dcaec19cSAlexander von Gluck IV message.Start(RP_DRAW_BITMAP_RECTS); 366dcaec19cSAlexander von Gluck IV message.Add(fToken); 367dcaec19cSAlexander von Gluck IV message.Add(options); 368dcaec19cSAlexander von Gluck IV message.Add(bitmap->ColorSpace()); 369dcaec19cSAlexander von Gluck IV message.Add(bitmap->Flags()); 370dcaec19cSAlexander von Gluck IV message.Add(rectCount); 371dcaec19cSAlexander von Gluck IV 372dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < rectCount; i++) { 373dcaec19cSAlexander von Gluck IV message.Add(clippedRegion.RectAt(i)); 374dcaec19cSAlexander von Gluck IV message.AddBitmap(*bitmaps[i], true); 375dcaec19cSAlexander von Gluck IV delete bitmaps[i]; 376dcaec19cSAlexander von Gluck IV } 377dcaec19cSAlexander von Gluck IV 378dcaec19cSAlexander von Gluck IV free(bitmaps); 379dcaec19cSAlexander von Gluck IV return; 380dcaec19cSAlexander von Gluck IV } 381dcaec19cSAlexander von Gluck IV 382dcaec19cSAlexander von Gluck IV // TODO: we may want to cache/checksum bitmaps 383dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 384dcaec19cSAlexander von Gluck IV message.Start(RP_DRAW_BITMAP); 385dcaec19cSAlexander von Gluck IV message.Add(fToken); 386dcaec19cSAlexander von Gluck IV message.Add(bitmapRect); 387dcaec19cSAlexander von Gluck IV message.Add(viewRect); 388dcaec19cSAlexander von Gluck IV message.Add(options); 389dcaec19cSAlexander von Gluck IV message.AddBitmap(*bitmap); 390dcaec19cSAlexander von Gluck IV } 391dcaec19cSAlexander von Gluck IV 392dcaec19cSAlexander von Gluck IV 393dcaec19cSAlexander von Gluck IV void 394dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawArc(BRect rect, const float& angle, const float& span, 395dcaec19cSAlexander von Gluck IV bool filled) 396dcaec19cSAlexander von Gluck IV { 397dcaec19cSAlexander von Gluck IV BRect bounds = rect; 398dcaec19cSAlexander von Gluck IV if (!filled) 399dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 400dcaec19cSAlexander von Gluck IV 401dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 402dcaec19cSAlexander von Gluck IV return; 403dcaec19cSAlexander von Gluck IV 404dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 405dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_ARC : RP_STROKE_ARC); 406dcaec19cSAlexander von Gluck IV message.Add(fToken); 407dcaec19cSAlexander von Gluck IV message.Add(rect); 408dcaec19cSAlexander von Gluck IV message.Add(angle); 409dcaec19cSAlexander von Gluck IV message.Add(span); 410dcaec19cSAlexander von Gluck IV } 411dcaec19cSAlexander von Gluck IV 412dcaec19cSAlexander von Gluck IV void 413dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillArc(BRect rect, const float& angle, const float& span, 414dcaec19cSAlexander von Gluck IV const BGradient& gradient) 415dcaec19cSAlexander von Gluck IV { 416dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 417dcaec19cSAlexander von Gluck IV return; 418dcaec19cSAlexander von Gluck IV 419dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 420dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_ARC_GRADIENT); 421dcaec19cSAlexander von Gluck IV message.Add(fToken); 422dcaec19cSAlexander von Gluck IV message.Add(rect); 423dcaec19cSAlexander von Gluck IV message.Add(angle); 424dcaec19cSAlexander von Gluck IV message.Add(span); 425dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 426dcaec19cSAlexander von Gluck IV } 427dcaec19cSAlexander von Gluck IV 428dcaec19cSAlexander von Gluck IV 429dcaec19cSAlexander von Gluck IV void 430dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawBezier(BPoint* points, bool filled) 431dcaec19cSAlexander von Gluck IV { 432dcaec19cSAlexander von Gluck IV BRect bounds = _BuildBounds(points, 4); 433dcaec19cSAlexander von Gluck IV if (!filled) 434dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 435dcaec19cSAlexander von Gluck IV 436dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 437dcaec19cSAlexander von Gluck IV return; 438dcaec19cSAlexander von Gluck IV 439dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 440dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_BEZIER : RP_STROKE_BEZIER); 441dcaec19cSAlexander von Gluck IV message.Add(fToken); 442dcaec19cSAlexander von Gluck IV message.AddList(points, 4); 443dcaec19cSAlexander von Gluck IV } 444dcaec19cSAlexander von Gluck IV 445dcaec19cSAlexander von Gluck IV 446dcaec19cSAlexander von Gluck IV void 447dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillBezier(BPoint* points, const BGradient& gradient) 448dcaec19cSAlexander von Gluck IV { 449dcaec19cSAlexander von Gluck IV BRect bounds = _BuildBounds(points, 4); 450dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 451dcaec19cSAlexander von Gluck IV return; 452dcaec19cSAlexander von Gluck IV 453dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 454dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_BEZIER_GRADIENT); 455dcaec19cSAlexander von Gluck IV message.Add(fToken); 456dcaec19cSAlexander von Gluck IV message.AddList(points, 4); 457dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 458dcaec19cSAlexander von Gluck IV } 459dcaec19cSAlexander von Gluck IV 460dcaec19cSAlexander von Gluck IV 461dcaec19cSAlexander von Gluck IV void 462dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawEllipse(BRect rect, bool filled) 463dcaec19cSAlexander von Gluck IV { 464dcaec19cSAlexander von Gluck IV BRect bounds = rect; 465dcaec19cSAlexander von Gluck IV if (!filled) 466dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 467dcaec19cSAlexander von Gluck IV 468dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 469dcaec19cSAlexander von Gluck IV return; 470dcaec19cSAlexander von Gluck IV 471dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 472dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_ELLIPSE : RP_STROKE_ELLIPSE); 473dcaec19cSAlexander von Gluck IV message.Add(fToken); 474dcaec19cSAlexander von Gluck IV message.Add(rect); 475dcaec19cSAlexander von Gluck IV } 476dcaec19cSAlexander von Gluck IV 477dcaec19cSAlexander von Gluck IV 478dcaec19cSAlexander von Gluck IV void 479dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillEllipse(BRect rect, const BGradient& gradient) 480dcaec19cSAlexander von Gluck IV { 481dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 482dcaec19cSAlexander von Gluck IV return; 483dcaec19cSAlexander von Gluck IV 484dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 485dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_ELLIPSE_GRADIENT); 486dcaec19cSAlexander von Gluck IV message.Add(fToken); 487dcaec19cSAlexander von Gluck IV message.Add(rect); 488dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 489dcaec19cSAlexander von Gluck IV } 490dcaec19cSAlexander von Gluck IV 491dcaec19cSAlexander von Gluck IV 492dcaec19cSAlexander von Gluck IV void 493dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawPolygon(BPoint* pointList, int32 numPoints, 494dcaec19cSAlexander von Gluck IV BRect bounds, bool filled, bool closed) 495dcaec19cSAlexander von Gluck IV { 496dcaec19cSAlexander von Gluck IV BRect clipBounds = bounds; 497dcaec19cSAlexander von Gluck IV if (!filled) 498dcaec19cSAlexander von Gluck IV clipBounds.InsetBy(fExtendWidth, fExtendWidth); 499dcaec19cSAlexander von Gluck IV 500dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(clipBounds)) 501dcaec19cSAlexander von Gluck IV return; 502dcaec19cSAlexander von Gluck IV 503dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 504dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_POLYGON : RP_STROKE_POLYGON); 505dcaec19cSAlexander von Gluck IV message.Add(fToken); 506dcaec19cSAlexander von Gluck IV message.Add(bounds); 507dcaec19cSAlexander von Gluck IV message.Add(closed); 508dcaec19cSAlexander von Gluck IV message.Add(numPoints); 509dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < numPoints; i++) 510dcaec19cSAlexander von Gluck IV message.Add(pointList[i]); 511dcaec19cSAlexander von Gluck IV } 512dcaec19cSAlexander von Gluck IV 513dcaec19cSAlexander von Gluck IV 514dcaec19cSAlexander von Gluck IV void 515dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillPolygon(BPoint* pointList, int32 numPoints, 516dcaec19cSAlexander von Gluck IV BRect bounds, const BGradient& gradient, bool closed) 517dcaec19cSAlexander von Gluck IV { 518dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 519dcaec19cSAlexander von Gluck IV return; 520dcaec19cSAlexander von Gluck IV 521dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 522dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_POLYGON_GRADIENT); 523dcaec19cSAlexander von Gluck IV message.Add(fToken); 524dcaec19cSAlexander von Gluck IV message.Add(bounds); 525dcaec19cSAlexander von Gluck IV message.Add(closed); 526dcaec19cSAlexander von Gluck IV message.Add(numPoints); 527dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < numPoints; i++) 528dcaec19cSAlexander von Gluck IV message.Add(pointList[i]); 529dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 530dcaec19cSAlexander von Gluck IV } 531dcaec19cSAlexander von Gluck IV 532dcaec19cSAlexander von Gluck IV 533dcaec19cSAlexander von Gluck IV // #pragma mark - rgb_color versions 534dcaec19cSAlexander von Gluck IV 535dcaec19cSAlexander von Gluck IV 536dcaec19cSAlexander von Gluck IV void 537dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokePoint(const BPoint& point, const rgb_color& color) 538dcaec19cSAlexander von Gluck IV { 539dcaec19cSAlexander von Gluck IV BRect bounds(point, point); 540dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 541dcaec19cSAlexander von Gluck IV 542dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 543dcaec19cSAlexander von Gluck IV return; 544dcaec19cSAlexander von Gluck IV 545dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 546dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_POINT_COLOR); 547dcaec19cSAlexander von Gluck IV message.Add(fToken); 548dcaec19cSAlexander von Gluck IV message.Add(point); 549dcaec19cSAlexander von Gluck IV message.Add(color); 550dcaec19cSAlexander von Gluck IV } 551dcaec19cSAlexander von Gluck IV 552dcaec19cSAlexander von Gluck IV 553dcaec19cSAlexander von Gluck IV void 554dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeLine(const BPoint& start, const BPoint& end, 555dcaec19cSAlexander von Gluck IV const rgb_color& color) 556dcaec19cSAlexander von Gluck IV { 557dcaec19cSAlexander von Gluck IV BPoint points[2] = { start, end }; 558dcaec19cSAlexander von Gluck IV BRect bounds = _BuildBounds(points, 2); 559dcaec19cSAlexander von Gluck IV 560dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 561dcaec19cSAlexander von Gluck IV return; 562dcaec19cSAlexander von Gluck IV 563dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 564dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_LINE_1PX_COLOR); 565dcaec19cSAlexander von Gluck IV message.Add(fToken); 566dcaec19cSAlexander von Gluck IV message.AddList(points, 2); 567dcaec19cSAlexander von Gluck IV message.Add(color); 568dcaec19cSAlexander von Gluck IV } 569dcaec19cSAlexander von Gluck IV 570dcaec19cSAlexander von Gluck IV 571dcaec19cSAlexander von Gluck IV void 572dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeRect(BRect rect, const rgb_color &color) 573dcaec19cSAlexander von Gluck IV { 574dcaec19cSAlexander von Gluck IV BRect bounds = rect; 575dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 576dcaec19cSAlexander von Gluck IV 577dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 578dcaec19cSAlexander von Gluck IV return; 579dcaec19cSAlexander von Gluck IV 580dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 581dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_RECT_1PX_COLOR); 582dcaec19cSAlexander von Gluck IV message.Add(fToken); 583dcaec19cSAlexander von Gluck IV message.Add(rect); 584dcaec19cSAlexander von Gluck IV message.Add(color); 585dcaec19cSAlexander von Gluck IV } 586dcaec19cSAlexander von Gluck IV 587dcaec19cSAlexander von Gluck IV 588dcaec19cSAlexander von Gluck IV void 589dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRect(BRect rect, const rgb_color& color) 590dcaec19cSAlexander von Gluck IV { 591dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 592dcaec19cSAlexander von Gluck IV return; 593dcaec19cSAlexander von Gluck IV 594dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 595dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_RECT_COLOR); 596dcaec19cSAlexander von Gluck IV message.Add(fToken); 597dcaec19cSAlexander von Gluck IV message.Add(rect); 598dcaec19cSAlexander von Gluck IV message.Add(color); 599dcaec19cSAlexander von Gluck IV } 600dcaec19cSAlexander von Gluck IV 601dcaec19cSAlexander von Gluck IV 602dcaec19cSAlexander von Gluck IV void 603dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRegion(BRegion& region, const rgb_color& color) 604dcaec19cSAlexander von Gluck IV { 605dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 606dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_REGION_COLOR_NO_CLIPPING); 607dcaec19cSAlexander von Gluck IV message.AddRegion(region); 608dcaec19cSAlexander von Gluck IV message.Add(color); 609dcaec19cSAlexander von Gluck IV } 610dcaec19cSAlexander von Gluck IV 611dcaec19cSAlexander von Gluck IV 612dcaec19cSAlexander von Gluck IV // #pragma mark - DrawState versions 613dcaec19cSAlexander von Gluck IV 614dcaec19cSAlexander von Gluck IV 615dcaec19cSAlexander von Gluck IV void 616dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeRect(BRect rect) 617dcaec19cSAlexander von Gluck IV { 618dcaec19cSAlexander von Gluck IV BRect bounds = rect; 619dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 620dcaec19cSAlexander von Gluck IV 621dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 622dcaec19cSAlexander von Gluck IV return; 623dcaec19cSAlexander von Gluck IV 624dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 625dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_RECT); 626dcaec19cSAlexander von Gluck IV message.Add(fToken); 627dcaec19cSAlexander von Gluck IV message.Add(rect); 628dcaec19cSAlexander von Gluck IV } 629dcaec19cSAlexander von Gluck IV 630dcaec19cSAlexander von Gluck IV 631dcaec19cSAlexander von Gluck IV void 632dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRect(BRect rect) 633dcaec19cSAlexander von Gluck IV { 634dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 635dcaec19cSAlexander von Gluck IV return; 636dcaec19cSAlexander von Gluck IV 637dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 638dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_RECT); 639dcaec19cSAlexander von Gluck IV message.Add(fToken); 640dcaec19cSAlexander von Gluck IV message.Add(rect); 641dcaec19cSAlexander von Gluck IV } 642dcaec19cSAlexander von Gluck IV 643dcaec19cSAlexander von Gluck IV 644dcaec19cSAlexander von Gluck IV void 645dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRect(BRect rect, const BGradient& gradient) 646dcaec19cSAlexander von Gluck IV { 647dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 648dcaec19cSAlexander von Gluck IV return; 649dcaec19cSAlexander von Gluck IV 650dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 651dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_RECT_GRADIENT); 652dcaec19cSAlexander von Gluck IV message.Add(fToken); 653dcaec19cSAlexander von Gluck IV message.Add(rect); 654dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 655dcaec19cSAlexander von Gluck IV } 656dcaec19cSAlexander von Gluck IV 657dcaec19cSAlexander von Gluck IV 658dcaec19cSAlexander von Gluck IV void 659dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRegion(BRegion& region) 660dcaec19cSAlexander von Gluck IV { 661dcaec19cSAlexander von Gluck IV BRegion clippedRegion = region; 662dcaec19cSAlexander von Gluck IV clippedRegion.IntersectWith(&fClippingRegion); 663dcaec19cSAlexander von Gluck IV if (clippedRegion.CountRects() == 0) 664dcaec19cSAlexander von Gluck IV return; 665dcaec19cSAlexander von Gluck IV 666dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 667dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_REGION); 668dcaec19cSAlexander von Gluck IV message.Add(fToken); 669dcaec19cSAlexander von Gluck IV message.AddRegion(clippedRegion.CountRects() < region.CountRects() 670dcaec19cSAlexander von Gluck IV ? clippedRegion : region); 671dcaec19cSAlexander von Gluck IV } 672dcaec19cSAlexander von Gluck IV 673dcaec19cSAlexander von Gluck IV 674dcaec19cSAlexander von Gluck IV void 675dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRegion(BRegion& region, const BGradient& gradient) 676dcaec19cSAlexander von Gluck IV { 677dcaec19cSAlexander von Gluck IV BRegion clippedRegion = region; 678dcaec19cSAlexander von Gluck IV clippedRegion.IntersectWith(&fClippingRegion); 679dcaec19cSAlexander von Gluck IV if (clippedRegion.CountRects() == 0) 680dcaec19cSAlexander von Gluck IV return; 681dcaec19cSAlexander von Gluck IV 682dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 683dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_REGION_GRADIENT); 684dcaec19cSAlexander von Gluck IV message.Add(fToken); 685dcaec19cSAlexander von Gluck IV message.AddRegion(clippedRegion.CountRects() < region.CountRects() 686dcaec19cSAlexander von Gluck IV ? clippedRegion : region); 687dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 688dcaec19cSAlexander von Gluck IV } 689dcaec19cSAlexander von Gluck IV 690dcaec19cSAlexander von Gluck IV 691dcaec19cSAlexander von Gluck IV void 692dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawRoundRect(BRect rect, float xRadius, float yRadius, 693dcaec19cSAlexander von Gluck IV bool filled) 694dcaec19cSAlexander von Gluck IV { 695dcaec19cSAlexander von Gluck IV BRect bounds = rect; 696dcaec19cSAlexander von Gluck IV if (!filled) 697dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 698dcaec19cSAlexander von Gluck IV 699dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 700dcaec19cSAlexander von Gluck IV return; 701dcaec19cSAlexander von Gluck IV 702dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 703dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_ROUND_RECT : RP_STROKE_ROUND_RECT); 704dcaec19cSAlexander von Gluck IV message.Add(fToken); 705dcaec19cSAlexander von Gluck IV message.Add(rect); 706dcaec19cSAlexander von Gluck IV message.Add(xRadius); 707dcaec19cSAlexander von Gluck IV message.Add(yRadius); 708dcaec19cSAlexander von Gluck IV } 709dcaec19cSAlexander von Gluck IV 710dcaec19cSAlexander von Gluck IV 711dcaec19cSAlexander von Gluck IV void 712dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRoundRect(BRect rect, float xRadius, float yRadius, 713dcaec19cSAlexander von Gluck IV const BGradient& gradient) 714dcaec19cSAlexander von Gluck IV { 715dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 716dcaec19cSAlexander von Gluck IV return; 717dcaec19cSAlexander von Gluck IV 718dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 719dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_ROUND_RECT_GRADIENT); 720dcaec19cSAlexander von Gluck IV message.Add(fToken); 721dcaec19cSAlexander von Gluck IV message.Add(rect); 722dcaec19cSAlexander von Gluck IV message.Add(xRadius); 723dcaec19cSAlexander von Gluck IV message.Add(yRadius); 724dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 725dcaec19cSAlexander von Gluck IV } 726dcaec19cSAlexander von Gluck IV 727dcaec19cSAlexander von Gluck IV 728dcaec19cSAlexander von Gluck IV void 729dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawShape(const BRect& bounds, int32 opCount, 730dcaec19cSAlexander von Gluck IV const uint32* opList, int32 pointCount, const BPoint* pointList, 731dcaec19cSAlexander von Gluck IV bool filled, const BPoint& viewToScreenOffset, float viewScale) 732dcaec19cSAlexander von Gluck IV { 733dcaec19cSAlexander von Gluck IV BRect clipBounds = bounds; 734dcaec19cSAlexander von Gluck IV if (!filled) 735dcaec19cSAlexander von Gluck IV clipBounds.InsetBy(fExtendWidth, fExtendWidth); 736dcaec19cSAlexander von Gluck IV 737dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(clipBounds)) 738dcaec19cSAlexander von Gluck IV return; 739dcaec19cSAlexander von Gluck IV 740dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 741dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_SHAPE : RP_STROKE_SHAPE); 742dcaec19cSAlexander von Gluck IV message.Add(fToken); 743dcaec19cSAlexander von Gluck IV message.Add(bounds); 744dcaec19cSAlexander von Gluck IV message.Add(opCount); 745dcaec19cSAlexander von Gluck IV message.AddList(opList, opCount); 746dcaec19cSAlexander von Gluck IV message.Add(pointCount); 747dcaec19cSAlexander von Gluck IV message.AddList(pointList, pointCount); 748dcaec19cSAlexander von Gluck IV message.Add(viewToScreenOffset); 749dcaec19cSAlexander von Gluck IV message.Add(viewScale); 750dcaec19cSAlexander von Gluck IV } 751dcaec19cSAlexander von Gluck IV 752dcaec19cSAlexander von Gluck IV 753dcaec19cSAlexander von Gluck IV void 754dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillShape(const BRect& bounds, int32 opCount, 755dcaec19cSAlexander von Gluck IV const uint32* opList, int32 pointCount, const BPoint* pointList, 756dcaec19cSAlexander von Gluck IV const BGradient& gradient, const BPoint& viewToScreenOffset, 757dcaec19cSAlexander von Gluck IV float viewScale) 758dcaec19cSAlexander von Gluck IV { 759dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 760dcaec19cSAlexander von Gluck IV return; 761dcaec19cSAlexander von Gluck IV 762dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 763dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_SHAPE_GRADIENT); 764dcaec19cSAlexander von Gluck IV message.Add(fToken); 765dcaec19cSAlexander von Gluck IV message.Add(bounds); 766dcaec19cSAlexander von Gluck IV message.Add(opCount); 767dcaec19cSAlexander von Gluck IV message.AddList(opList, opCount); 768dcaec19cSAlexander von Gluck IV message.Add(pointCount); 769dcaec19cSAlexander von Gluck IV message.AddList(pointList, pointCount); 770dcaec19cSAlexander von Gluck IV message.Add(viewToScreenOffset); 771dcaec19cSAlexander von Gluck IV message.Add(viewScale); 772*df55bcf5SMichael Lotz message.AddGradient(gradient); 773dcaec19cSAlexander von Gluck IV } 774dcaec19cSAlexander von Gluck IV 775dcaec19cSAlexander von Gluck IV 776dcaec19cSAlexander von Gluck IV void 777dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawTriangle(BPoint* points, const BRect& bounds, 778dcaec19cSAlexander von Gluck IV bool filled) 779dcaec19cSAlexander von Gluck IV { 780dcaec19cSAlexander von Gluck IV BRect clipBounds = bounds; 781dcaec19cSAlexander von Gluck IV if (!filled) 782dcaec19cSAlexander von Gluck IV clipBounds.InsetBy(fExtendWidth, fExtendWidth); 783dcaec19cSAlexander von Gluck IV 784dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(clipBounds)) 785dcaec19cSAlexander von Gluck IV return; 786dcaec19cSAlexander von Gluck IV 787dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 788dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_TRIANGLE : RP_STROKE_TRIANGLE); 789dcaec19cSAlexander von Gluck IV message.Add(fToken); 790dcaec19cSAlexander von Gluck IV message.AddList(points, 3); 791dcaec19cSAlexander von Gluck IV message.Add(bounds); 792dcaec19cSAlexander von Gluck IV } 793dcaec19cSAlexander von Gluck IV 794dcaec19cSAlexander von Gluck IV 795dcaec19cSAlexander von Gluck IV void 796dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillTriangle(BPoint* points, const BRect& bounds, 797dcaec19cSAlexander von Gluck IV const BGradient& gradient) 798dcaec19cSAlexander von Gluck IV { 799dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 800dcaec19cSAlexander von Gluck IV return; 801dcaec19cSAlexander von Gluck IV 802dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 803dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_TRIANGLE_GRADIENT); 804dcaec19cSAlexander von Gluck IV message.Add(fToken); 805dcaec19cSAlexander von Gluck IV message.Add(points[0]); 806dcaec19cSAlexander von Gluck IV message.Add(points[1]); 807dcaec19cSAlexander von Gluck IV message.Add(points[2]); 808dcaec19cSAlexander von Gluck IV message.Add(bounds); 809dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 810dcaec19cSAlexander von Gluck IV } 811dcaec19cSAlexander von Gluck IV 812dcaec19cSAlexander von Gluck IV 813dcaec19cSAlexander von Gluck IV void 814dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeLine(const BPoint &start, const BPoint &end) 815dcaec19cSAlexander von Gluck IV { 816dcaec19cSAlexander von Gluck IV BPoint points[2] = { start, end }; 817dcaec19cSAlexander von Gluck IV BRect bounds = _BuildBounds(points, 2); 818dcaec19cSAlexander von Gluck IV 819dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 820dcaec19cSAlexander von Gluck IV return; 821dcaec19cSAlexander von Gluck IV 822dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 823dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_LINE); 824dcaec19cSAlexander von Gluck IV message.Add(fToken); 825dcaec19cSAlexander von Gluck IV message.AddList(points, 2); 826dcaec19cSAlexander von Gluck IV } 827dcaec19cSAlexander von Gluck IV 828dcaec19cSAlexander von Gluck IV 829dcaec19cSAlexander von Gluck IV void 830dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeLineArray(int32 numLines, 831dcaec19cSAlexander von Gluck IV const ViewLineArrayInfo *lineData) 832dcaec19cSAlexander von Gluck IV { 833dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 834dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_LINE_ARRAY); 835dcaec19cSAlexander von Gluck IV message.Add(fToken); 836dcaec19cSAlexander von Gluck IV message.Add(numLines); 837dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < numLines; i++) 838dcaec19cSAlexander von Gluck IV message.AddArrayLine(lineData[i]); 839dcaec19cSAlexander von Gluck IV } 840dcaec19cSAlexander von Gluck IV 841dcaec19cSAlexander von Gluck IV 842dcaec19cSAlexander von Gluck IV // #pragma mark - string functions 843dcaec19cSAlexander von Gluck IV 844dcaec19cSAlexander von Gluck IV 845dcaec19cSAlexander von Gluck IV BPoint 846dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawString(const char* string, int32 length, 847dcaec19cSAlexander von Gluck IV const BPoint& point, escapement_delta* delta) 848dcaec19cSAlexander von Gluck IV { 849dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 850dcaec19cSAlexander von Gluck IV 851dcaec19cSAlexander von Gluck IV message.Start(RP_DRAW_STRING); 852dcaec19cSAlexander von Gluck IV message.Add(fToken); 853dcaec19cSAlexander von Gluck IV message.Add(point); 854dcaec19cSAlexander von Gluck IV message.AddString(string, length); 855dcaec19cSAlexander von Gluck IV message.Add(delta != NULL); 856dcaec19cSAlexander von Gluck IV if (delta != NULL) 857dcaec19cSAlexander von Gluck IV message.AddList(delta, length); 858dcaec19cSAlexander von Gluck IV 859dcaec19cSAlexander von Gluck IV status_t result = _AddCallback(); 860dcaec19cSAlexander von Gluck IV if (message.Flush() != B_OK) 861dcaec19cSAlexander von Gluck IV return point; 862dcaec19cSAlexander von Gluck IV 863dcaec19cSAlexander von Gluck IV if (result != B_OK) 864dcaec19cSAlexander von Gluck IV return point; 865dcaec19cSAlexander von Gluck IV 866dcaec19cSAlexander von Gluck IV do { 867dcaec19cSAlexander von Gluck IV result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 868dcaec19cSAlexander von Gluck IV 1 * 1000 * 1000); 869dcaec19cSAlexander von Gluck IV } while (result == B_INTERRUPTED); 870dcaec19cSAlexander von Gluck IV 871dcaec19cSAlexander von Gluck IV if (result != B_OK) 872dcaec19cSAlexander von Gluck IV return point; 873dcaec19cSAlexander von Gluck IV 874dcaec19cSAlexander von Gluck IV return fDrawStringResult; 875dcaec19cSAlexander von Gluck IV } 876dcaec19cSAlexander von Gluck IV 877dcaec19cSAlexander von Gluck IV 878dcaec19cSAlexander von Gluck IV BPoint 879dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawString(const char* string, int32 length, 880dcaec19cSAlexander von Gluck IV const BPoint* offsets) 881dcaec19cSAlexander von Gluck IV { 882dcaec19cSAlexander von Gluck IV // Guaranteed to have at least one point. 883dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 884dcaec19cSAlexander von Gluck IV 885dcaec19cSAlexander von Gluck IV message.Start(RP_DRAW_STRING_WITH_OFFSETS); 886dcaec19cSAlexander von Gluck IV message.Add(fToken); 887dcaec19cSAlexander von Gluck IV message.AddString(string, length); 888dcaec19cSAlexander von Gluck IV message.AddList(offsets, UTF8CountChars(string, length)); 889dcaec19cSAlexander von Gluck IV 890dcaec19cSAlexander von Gluck IV status_t result = _AddCallback(); 891dcaec19cSAlexander von Gluck IV if (message.Flush() != B_OK) 892dcaec19cSAlexander von Gluck IV return offsets[0]; 893dcaec19cSAlexander von Gluck IV 894dcaec19cSAlexander von Gluck IV if (result != B_OK) 895dcaec19cSAlexander von Gluck IV return offsets[0]; 896dcaec19cSAlexander von Gluck IV 897dcaec19cSAlexander von Gluck IV do { 898dcaec19cSAlexander von Gluck IV result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 899dcaec19cSAlexander von Gluck IV 1 * 1000 * 1000); 900dcaec19cSAlexander von Gluck IV } while (result == B_INTERRUPTED); 901dcaec19cSAlexander von Gluck IV 902dcaec19cSAlexander von Gluck IV if (result != B_OK) 903dcaec19cSAlexander von Gluck IV return offsets[0]; 904dcaec19cSAlexander von Gluck IV 905dcaec19cSAlexander von Gluck IV return fDrawStringResult; 906dcaec19cSAlexander von Gluck IV } 907dcaec19cSAlexander von Gluck IV 908dcaec19cSAlexander von Gluck IV 909dcaec19cSAlexander von Gluck IV float 910dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StringWidth(const char* string, int32 length, 911dcaec19cSAlexander von Gluck IV escapement_delta* delta) 912dcaec19cSAlexander von Gluck IV { 913dcaec19cSAlexander von Gluck IV // TODO: decide if really needed and use callback if so 914dcaec19cSAlexander von Gluck IV return fState.Font().StringWidth(string, length, delta); 915dcaec19cSAlexander von Gluck IV } 916dcaec19cSAlexander von Gluck IV 917dcaec19cSAlexander von Gluck IV 918dcaec19cSAlexander von Gluck IV // #pragma mark - 919dcaec19cSAlexander von Gluck IV 920dcaec19cSAlexander von Gluck IV 921dcaec19cSAlexander von Gluck IV status_t 922dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::ReadBitmap(ServerBitmap* bitmap, bool drawCursor, 923dcaec19cSAlexander von Gluck IV BRect bounds) 924dcaec19cSAlexander von Gluck IV { 925dcaec19cSAlexander von Gluck IV if (_AddCallback() != B_OK) 926dcaec19cSAlexander von Gluck IV return B_UNSUPPORTED; 927dcaec19cSAlexander von Gluck IV 928dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 929dcaec19cSAlexander von Gluck IV 930dcaec19cSAlexander von Gluck IV message.Start(RP_READ_BITMAP); 931dcaec19cSAlexander von Gluck IV message.Add(fToken); 932dcaec19cSAlexander von Gluck IV message.Add(bounds); 933dcaec19cSAlexander von Gluck IV message.Add(drawCursor); 934dcaec19cSAlexander von Gluck IV if (message.Flush() != B_OK) 935dcaec19cSAlexander von Gluck IV return B_UNSUPPORTED; 936dcaec19cSAlexander von Gluck IV 937dcaec19cSAlexander von Gluck IV status_t result; 938dcaec19cSAlexander von Gluck IV do { 939dcaec19cSAlexander von Gluck IV result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 940dcaec19cSAlexander von Gluck IV 100 * 1000 * 1000); 941dcaec19cSAlexander von Gluck IV } while (result == B_INTERRUPTED); 942dcaec19cSAlexander von Gluck IV 943dcaec19cSAlexander von Gluck IV if (result != B_OK) 944dcaec19cSAlexander von Gluck IV return result; 945dcaec19cSAlexander von Gluck IV 946dcaec19cSAlexander von Gluck IV BBitmap* read = fReadBitmapResult; 947dcaec19cSAlexander von Gluck IV if (read == NULL) 948dcaec19cSAlexander von Gluck IV return B_UNSUPPORTED; 949dcaec19cSAlexander von Gluck IV 950dcaec19cSAlexander von Gluck IV result = bitmap->ImportBits(read->Bits(), read->BitsLength(), 951dcaec19cSAlexander von Gluck IV read->BytesPerRow(), read->ColorSpace()); 952dcaec19cSAlexander von Gluck IV delete read; 953dcaec19cSAlexander von Gluck IV return result; 954dcaec19cSAlexander von Gluck IV } 955dcaec19cSAlexander von Gluck IV 956dcaec19cSAlexander von Gluck IV 957dcaec19cSAlexander von Gluck IV // #pragma mark - 958dcaec19cSAlexander von Gluck IV 959dcaec19cSAlexander von Gluck IV 960dcaec19cSAlexander von Gluck IV status_t 961dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::_AddCallback() 962dcaec19cSAlexander von Gluck IV { 963dcaec19cSAlexander von Gluck IV if (fCallbackAdded) 964dcaec19cSAlexander von Gluck IV return B_OK; 965dcaec19cSAlexander von Gluck IV 966dcaec19cSAlexander von Gluck IV if (fResultNotify < 0) 967dcaec19cSAlexander von Gluck IV fResultNotify = create_sem(0, "drawing engine result"); 968dcaec19cSAlexander von Gluck IV if (fResultNotify < 0) 969dcaec19cSAlexander von Gluck IV return fResultNotify; 970dcaec19cSAlexander von Gluck IV 971dcaec19cSAlexander von Gluck IV status_t result = fHWInterface->AddCallback(fToken, &_DrawingEngineResult, 972dcaec19cSAlexander von Gluck IV this); 973dcaec19cSAlexander von Gluck IV 974dcaec19cSAlexander von Gluck IV fCallbackAdded = result == B_OK; 975dcaec19cSAlexander von Gluck IV return result; 976dcaec19cSAlexander von Gluck IV } 977dcaec19cSAlexander von Gluck IV 978dcaec19cSAlexander von Gluck IV 979dcaec19cSAlexander von Gluck IV bool 980dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::_DrawingEngineResult(void* cookie, RemoteMessage& message) 981dcaec19cSAlexander von Gluck IV { 982dcaec19cSAlexander von Gluck IV RemoteDrawingEngine* engine = (RemoteDrawingEngine*)cookie; 983dcaec19cSAlexander von Gluck IV 984dcaec19cSAlexander von Gluck IV switch (message.Code()) { 985dcaec19cSAlexander von Gluck IV case RP_DRAW_STRING_RESULT: 986dcaec19cSAlexander von Gluck IV if (message.Read(engine->fDrawStringResult) != B_OK) 987dcaec19cSAlexander von Gluck IV return false; 988dcaec19cSAlexander von Gluck IV break; 989dcaec19cSAlexander von Gluck IV 990dcaec19cSAlexander von Gluck IV case RP_STRING_WIDTH_RESULT: 991dcaec19cSAlexander von Gluck IV if (message.Read(engine->fStringWidthResult) != B_OK) 992dcaec19cSAlexander von Gluck IV return false; 993dcaec19cSAlexander von Gluck IV break; 994dcaec19cSAlexander von Gluck IV 995dcaec19cSAlexander von Gluck IV case RP_READ_BITMAP_RESULT: 996dcaec19cSAlexander von Gluck IV if (message.ReadBitmap(&engine->fReadBitmapResult) != B_OK) 997dcaec19cSAlexander von Gluck IV return false; 998dcaec19cSAlexander von Gluck IV break; 999dcaec19cSAlexander von Gluck IV 1000dcaec19cSAlexander von Gluck IV default: 1001dcaec19cSAlexander von Gluck IV return false; 1002dcaec19cSAlexander von Gluck IV } 1003dcaec19cSAlexander von Gluck IV 1004dcaec19cSAlexander von Gluck IV release_sem(engine->fResultNotify); 1005dcaec19cSAlexander von Gluck IV return true; 1006dcaec19cSAlexander von Gluck IV } 1007dcaec19cSAlexander von Gluck IV 1008dcaec19cSAlexander von Gluck IV 1009dcaec19cSAlexander von Gluck IV BRect 1010dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::_BuildBounds(BPoint* points, int32 pointCount) 1011dcaec19cSAlexander von Gluck IV { 1012dcaec19cSAlexander von Gluck IV BRect bounds(1000000, 1000000, 0, 0); 1013dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < pointCount; i++) { 1014dcaec19cSAlexander von Gluck IV bounds.left = min_c(bounds.left, points[i].x); 1015dcaec19cSAlexander von Gluck IV bounds.top = min_c(bounds.top, points[i].y); 1016dcaec19cSAlexander von Gluck IV bounds.right = max_c(bounds.right, points[i].x); 1017dcaec19cSAlexander von Gluck IV bounds.bottom = max_c(bounds.bottom, points[i].y); 1018dcaec19cSAlexander von Gluck IV } 1019dcaec19cSAlexander von Gluck IV 1020dcaec19cSAlexander von Gluck IV return bounds; 1021dcaec19cSAlexander von Gluck IV } 1022dcaec19cSAlexander von Gluck IV 1023dcaec19cSAlexander von Gluck IV 1024dcaec19cSAlexander von Gluck IV status_t 1025dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::_ExtractBitmapRegions(ServerBitmap& bitmap, uint32 options, 1026dcaec19cSAlexander von Gluck IV const BRect& bitmapRect, const BRect& viewRect, double xScale, 1027dcaec19cSAlexander von Gluck IV double yScale, BRegion& region, UtilityBitmap**& bitmaps) 1028dcaec19cSAlexander von Gluck IV { 1029dcaec19cSAlexander von Gluck IV int32 rectCount = region.CountRects(); 1030dcaec19cSAlexander von Gluck IV bitmaps = (UtilityBitmap**)malloc(rectCount * sizeof(UtilityBitmap*)); 1031dcaec19cSAlexander von Gluck IV if (bitmaps == NULL) 1032dcaec19cSAlexander von Gluck IV return B_NO_MEMORY; 1033dcaec19cSAlexander von Gluck IV 1034dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < rectCount; i++) { 1035dcaec19cSAlexander von Gluck IV BRect sourceRect = region.RectAt(i).OffsetByCopy(-viewRect.LeftTop()); 1036dcaec19cSAlexander von Gluck IV int32 targetWidth = (int32)(sourceRect.Width() + 1.5); 1037dcaec19cSAlexander von Gluck IV int32 targetHeight = (int32)(sourceRect.Height() + 1.5); 1038dcaec19cSAlexander von Gluck IV 1039dcaec19cSAlexander von Gluck IV if (xScale != 1.0) { 1040dcaec19cSAlexander von Gluck IV sourceRect.left = (int32)(sourceRect.left * xScale + 0.5); 1041dcaec19cSAlexander von Gluck IV sourceRect.right = (int32)(sourceRect.right * xScale + 0.5); 1042dcaec19cSAlexander von Gluck IV if (xScale < 1.0) 1043dcaec19cSAlexander von Gluck IV targetWidth = (int32)(sourceRect.Width() + 1.5); 1044dcaec19cSAlexander von Gluck IV } 1045dcaec19cSAlexander von Gluck IV 1046dcaec19cSAlexander von Gluck IV if (yScale != 1.0) { 1047dcaec19cSAlexander von Gluck IV sourceRect.top = (int32)(sourceRect.top * yScale + 0.5); 1048dcaec19cSAlexander von Gluck IV sourceRect.bottom = (int32)(sourceRect.bottom * yScale + 0.5); 1049dcaec19cSAlexander von Gluck IV if (yScale < 1.0) 1050dcaec19cSAlexander von Gluck IV targetHeight = (int32)(sourceRect.Height() + 1.5); 1051dcaec19cSAlexander von Gluck IV } 1052dcaec19cSAlexander von Gluck IV 1053dcaec19cSAlexander von Gluck IV sourceRect.OffsetBy(bitmapRect.LeftTop()); 1054dcaec19cSAlexander von Gluck IV // sourceRect is now the part of the bitmap we want copied 1055dcaec19cSAlexander von Gluck IV 1056dcaec19cSAlexander von Gluck IV status_t result = B_OK; 1057dcaec19cSAlexander von Gluck IV if ((xScale > 1.0 || yScale > 1.0) 1058dcaec19cSAlexander von Gluck IV && (targetWidth * targetHeight < (int32)(sourceRect.Width() + 1.5) 1059dcaec19cSAlexander von Gluck IV * (int32)(sourceRect.Height() + 1.5))) { 1060dcaec19cSAlexander von Gluck IV // the target bitmap is smaller than the source, scale it locally 1061dcaec19cSAlexander von Gluck IV // and send over the smaller version to avoid sending any extra data 1062dcaec19cSAlexander von Gluck IV if (fBitmapDrawingEngine == NULL) { 1063dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine 1064dcaec19cSAlexander von Gluck IV = new(std::nothrow) BitmapDrawingEngine(B_RGBA32); 1065dcaec19cSAlexander von Gluck IV if (fBitmapDrawingEngine == NULL) 1066dcaec19cSAlexander von Gluck IV result = B_NO_MEMORY; 1067dcaec19cSAlexander von Gluck IV } 1068dcaec19cSAlexander von Gluck IV 1069dcaec19cSAlexander von Gluck IV if (result == B_OK) { 1070dcaec19cSAlexander von Gluck IV result = fBitmapDrawingEngine->SetSize(targetWidth, 1071dcaec19cSAlexander von Gluck IV targetHeight); 1072dcaec19cSAlexander von Gluck IV } 1073dcaec19cSAlexander von Gluck IV 1074dcaec19cSAlexander von Gluck IV if (result == B_OK) { 1075dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine->SetDrawingMode(B_OP_COPY); 1076dcaec19cSAlexander von Gluck IV 1077dcaec19cSAlexander von Gluck IV switch (bitmap.ColorSpace()) { 1078dcaec19cSAlexander von Gluck IV case B_RGBA32: 1079dcaec19cSAlexander von Gluck IV case B_RGBA32_BIG: 1080dcaec19cSAlexander von Gluck IV case B_RGBA15: 1081dcaec19cSAlexander von Gluck IV case B_RGBA15_BIG: 1082dcaec19cSAlexander von Gluck IV break; 1083dcaec19cSAlexander von Gluck IV 1084dcaec19cSAlexander von Gluck IV default: 1085dcaec19cSAlexander von Gluck IV { 1086dcaec19cSAlexander von Gluck IV // we need to clear the background if there may be 1087dcaec19cSAlexander von Gluck IV // transparency through transparent magic (we use 1088dcaec19cSAlexander von Gluck IV // B_OP_COPY when we draw alpha enabled bitmaps, so we 1089dcaec19cSAlexander von Gluck IV // don't need to clear there) 1090dcaec19cSAlexander von Gluck IV // TODO: this is not actually correct, as we're going to 1091dcaec19cSAlexander von Gluck IV // loose the transparency with the conversion to the 1092dcaec19cSAlexander von Gluck IV // original non-alpha colorspace happening in 1093dcaec19cSAlexander von Gluck IV // ExportToBitmap 1094dcaec19cSAlexander von Gluck IV rgb_color background = { 0, 0, 0, 0 }; 1095dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine->FillRect( 1096dcaec19cSAlexander von Gluck IV BRect(0, 0, targetWidth - 1, targetHeight -1), 1097dcaec19cSAlexander von Gluck IV background); 1098dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine->SetDrawingMode(B_OP_OVER); 1099dcaec19cSAlexander von Gluck IV break; 1100dcaec19cSAlexander von Gluck IV } 1101dcaec19cSAlexander von Gluck IV } 1102dcaec19cSAlexander von Gluck IV 1103dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine->DrawBitmap(&bitmap, sourceRect, 1104dcaec19cSAlexander von Gluck IV BRect(0, 0, targetWidth - 1, targetHeight - 1), options); 1105dcaec19cSAlexander von Gluck IV bitmaps[i] = fBitmapDrawingEngine->ExportToBitmap(targetWidth, 1106dcaec19cSAlexander von Gluck IV targetHeight, bitmap.ColorSpace()); 1107dcaec19cSAlexander von Gluck IV if (bitmaps[i] == NULL) 1108dcaec19cSAlexander von Gluck IV result = B_NO_MEMORY; 1109dcaec19cSAlexander von Gluck IV } 1110dcaec19cSAlexander von Gluck IV } else { 1111dcaec19cSAlexander von Gluck IV // source is smaller or equal target, extract the relevant rects 1112dcaec19cSAlexander von Gluck IV // directly without any scaling and conversion 1113dcaec19cSAlexander von Gluck IV targetWidth = (int32)(sourceRect.Width() + 1.5); 1114dcaec19cSAlexander von Gluck IV targetHeight = (int32)(sourceRect.Height() + 1.5); 1115dcaec19cSAlexander von Gluck IV 1116dcaec19cSAlexander von Gluck IV bitmaps[i] = new(std::nothrow) UtilityBitmap( 1117dcaec19cSAlexander von Gluck IV BRect(0, 0, targetWidth - 1, targetHeight - 1), 1118dcaec19cSAlexander von Gluck IV bitmap.ColorSpace(), 0); 1119c347a4d4SMurai Takashi if (bitmaps[i] == NULL) { 1120dcaec19cSAlexander von Gluck IV result = B_NO_MEMORY; 1121c347a4d4SMurai Takashi } else { 1122c347a4d4SMurai Takashi result = bitmaps[i]->ImportBits(bitmap.Bits(), 1123c347a4d4SMurai Takashi bitmap.BitsLength(), bitmap.BytesPerRow(), 1124c347a4d4SMurai Takashi bitmap.ColorSpace(), sourceRect.LeftTop(), 1125dcaec19cSAlexander von Gluck IV BPoint(0, 0), targetWidth, targetHeight); 1126c347a4d4SMurai Takashi if (result != B_OK) { 1127dcaec19cSAlexander von Gluck IV delete bitmaps[i]; 1128c347a4d4SMurai Takashi bitmaps[i] = NULL; 1129c347a4d4SMurai Takashi } 1130c347a4d4SMurai Takashi } 1131dcaec19cSAlexander von Gluck IV } 1132dcaec19cSAlexander von Gluck IV 1133dcaec19cSAlexander von Gluck IV if (result != B_OK) { 1134dcaec19cSAlexander von Gluck IV for (int32 j = 0; j < i; j++) 1135dcaec19cSAlexander von Gluck IV delete bitmaps[j]; 1136dcaec19cSAlexander von Gluck IV free(bitmaps); 1137dcaec19cSAlexander von Gluck IV return result; 1138dcaec19cSAlexander von Gluck IV } 1139dcaec19cSAlexander von Gluck IV } 1140dcaec19cSAlexander von Gluck IV 1141dcaec19cSAlexander von Gluck IV return B_OK; 1142dcaec19cSAlexander von Gluck IV } 1143