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()); 117*2e499128SX512 SetTransform(state->CombinedTransform(), xOffset, yOffset); 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 273*2e499128SX512 RemoteDrawingEngine::SetTransform(const BAffineTransform& transform, 274*2e499128SX512 int32 xOffset, int32 yOffset) 27591c1d3dbSMichael Lotz { 276*2e499128SX512 // TODO: take offset into account 277*2e499128SX512 27891c1d3dbSMichael Lotz if (fState.Transform() == transform) 27991c1d3dbSMichael Lotz return; 28091c1d3dbSMichael Lotz 28191c1d3dbSMichael Lotz fState.SetTransform(transform); 28291c1d3dbSMichael Lotz 28391c1d3dbSMichael Lotz RemoteMessage message(NULL, fHWInterface->SendBuffer()); 28491c1d3dbSMichael Lotz message.Start(RP_SET_TRANSFORM); 28591c1d3dbSMichael Lotz message.Add(fToken); 28691c1d3dbSMichael Lotz message.AddTransform(transform); 28791c1d3dbSMichael Lotz } 28891c1d3dbSMichael Lotz 28991c1d3dbSMichael Lotz 290dcaec19cSAlexander von Gluck IV // #pragma mark - 291dcaec19cSAlexander von Gluck IV 292dcaec19cSAlexander von Gluck IV 293dcaec19cSAlexander von Gluck IV BRect 294dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::CopyRect(BRect rect, int32 xOffset, int32 yOffset) const 295dcaec19cSAlexander von Gluck IV { 296dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 297dcaec19cSAlexander von Gluck IV message.Start(RP_COPY_RECT_NO_CLIPPING); 298dcaec19cSAlexander von Gluck IV message.Add(xOffset); 299dcaec19cSAlexander von Gluck IV message.Add(yOffset); 300dcaec19cSAlexander von Gluck IV message.Add(rect); 301dcaec19cSAlexander von Gluck IV return rect.OffsetBySelf(xOffset, yOffset); 302dcaec19cSAlexander von Gluck IV } 303dcaec19cSAlexander von Gluck IV 304dcaec19cSAlexander von Gluck IV 305dcaec19cSAlexander von Gluck IV void 306dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::InvertRect(BRect rect) 307dcaec19cSAlexander von Gluck IV { 308dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 309dcaec19cSAlexander von Gluck IV return; 310dcaec19cSAlexander von Gluck IV 311dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 312dcaec19cSAlexander von Gluck IV message.Start(RP_INVERT_RECT); 313dcaec19cSAlexander von Gluck IV message.Add(fToken); 314dcaec19cSAlexander von Gluck IV message.Add(rect); 315dcaec19cSAlexander von Gluck IV } 316dcaec19cSAlexander von Gluck IV 317dcaec19cSAlexander von Gluck IV 318dcaec19cSAlexander von Gluck IV void 319dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawBitmap(ServerBitmap* bitmap, const BRect& _bitmapRect, 320dcaec19cSAlexander von Gluck IV const BRect& _viewRect, uint32 options) 321dcaec19cSAlexander von Gluck IV { 322dcaec19cSAlexander von Gluck IV BRect bitmapRect = _bitmapRect; 323dcaec19cSAlexander von Gluck IV BRect viewRect = _viewRect; 324dcaec19cSAlexander von Gluck IV double xScale = (bitmapRect.Width() + 1) / (viewRect.Width() + 1); 325dcaec19cSAlexander von Gluck IV double yScale = (bitmapRect.Height() + 1) / (viewRect.Height() + 1); 326dcaec19cSAlexander von Gluck IV 327dcaec19cSAlexander von Gluck IV // constrain rect to passed bitmap bounds 328dcaec19cSAlexander von Gluck IV // and transfer the changes to the viewRect with the right scale 329dcaec19cSAlexander von Gluck IV BRect actualBitmapRect = bitmap->Bounds(); 330dcaec19cSAlexander von Gluck IV if (bitmapRect.left < actualBitmapRect.left) { 331dcaec19cSAlexander von Gluck IV float diff = actualBitmapRect.left - bitmapRect.left; 332dcaec19cSAlexander von Gluck IV viewRect.left += diff / xScale; 333dcaec19cSAlexander von Gluck IV bitmapRect.left = actualBitmapRect.left; 334dcaec19cSAlexander von Gluck IV } 335dcaec19cSAlexander von Gluck IV if (bitmapRect.top < actualBitmapRect.top) { 336dcaec19cSAlexander von Gluck IV float diff = actualBitmapRect.top - bitmapRect.top; 337dcaec19cSAlexander von Gluck IV viewRect.top += diff / yScale; 338dcaec19cSAlexander von Gluck IV bitmapRect.top = actualBitmapRect.top; 339dcaec19cSAlexander von Gluck IV } 340dcaec19cSAlexander von Gluck IV if (bitmapRect.right > actualBitmapRect.right) { 341dcaec19cSAlexander von Gluck IV float diff = bitmapRect.right - actualBitmapRect.right; 342dcaec19cSAlexander von Gluck IV viewRect.right -= diff / xScale; 343dcaec19cSAlexander von Gluck IV bitmapRect.right = actualBitmapRect.right; 344dcaec19cSAlexander von Gluck IV } 345dcaec19cSAlexander von Gluck IV if (bitmapRect.bottom > actualBitmapRect.bottom) { 346dcaec19cSAlexander von Gluck IV float diff = bitmapRect.bottom - actualBitmapRect.bottom; 347dcaec19cSAlexander von Gluck IV viewRect.bottom -= diff / yScale; 348dcaec19cSAlexander von Gluck IV bitmapRect.bottom = actualBitmapRect.bottom; 349dcaec19cSAlexander von Gluck IV } 350dcaec19cSAlexander von Gluck IV 351dcaec19cSAlexander von Gluck IV BRegion clippedRegion(viewRect); 352dcaec19cSAlexander von Gluck IV clippedRegion.IntersectWith(&fClippingRegion); 353dcaec19cSAlexander von Gluck IV 354dcaec19cSAlexander von Gluck IV int32 rectCount = clippedRegion.CountRects(); 355dcaec19cSAlexander von Gluck IV if (rectCount == 0) 356dcaec19cSAlexander von Gluck IV return; 357dcaec19cSAlexander von Gluck IV 358dcaec19cSAlexander von Gluck IV if (rectCount > 1 || (rectCount == 1 && clippedRegion.RectAt(0) != viewRect) 359dcaec19cSAlexander von Gluck IV || viewRect.Width() < bitmapRect.Width() 360dcaec19cSAlexander von Gluck IV || viewRect.Height() < bitmapRect.Height()) { 361dcaec19cSAlexander von Gluck IV UtilityBitmap** bitmaps; 362dcaec19cSAlexander von Gluck IV if (_ExtractBitmapRegions(*bitmap, options, bitmapRect, viewRect, 363dcaec19cSAlexander von Gluck IV xScale, yScale, clippedRegion, bitmaps) != B_OK) { 364dcaec19cSAlexander von Gluck IV return; 365dcaec19cSAlexander von Gluck IV } 366dcaec19cSAlexander von Gluck IV 367dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 368dcaec19cSAlexander von Gluck IV message.Start(RP_DRAW_BITMAP_RECTS); 369dcaec19cSAlexander von Gluck IV message.Add(fToken); 370dcaec19cSAlexander von Gluck IV message.Add(options); 371dcaec19cSAlexander von Gluck IV message.Add(bitmap->ColorSpace()); 372dcaec19cSAlexander von Gluck IV message.Add(bitmap->Flags()); 373dcaec19cSAlexander von Gluck IV message.Add(rectCount); 374dcaec19cSAlexander von Gluck IV 375dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < rectCount; i++) { 376dcaec19cSAlexander von Gluck IV message.Add(clippedRegion.RectAt(i)); 377dcaec19cSAlexander von Gluck IV message.AddBitmap(*bitmaps[i], true); 378dcaec19cSAlexander von Gluck IV delete bitmaps[i]; 379dcaec19cSAlexander von Gluck IV } 380dcaec19cSAlexander von Gluck IV 381dcaec19cSAlexander von Gluck IV free(bitmaps); 382dcaec19cSAlexander von Gluck IV return; 383dcaec19cSAlexander von Gluck IV } 384dcaec19cSAlexander von Gluck IV 385dcaec19cSAlexander von Gluck IV // TODO: we may want to cache/checksum bitmaps 386dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 387dcaec19cSAlexander von Gluck IV message.Start(RP_DRAW_BITMAP); 388dcaec19cSAlexander von Gluck IV message.Add(fToken); 389dcaec19cSAlexander von Gluck IV message.Add(bitmapRect); 390dcaec19cSAlexander von Gluck IV message.Add(viewRect); 391dcaec19cSAlexander von Gluck IV message.Add(options); 392dcaec19cSAlexander von Gluck IV message.AddBitmap(*bitmap); 393dcaec19cSAlexander von Gluck IV } 394dcaec19cSAlexander von Gluck IV 395dcaec19cSAlexander von Gluck IV 396dcaec19cSAlexander von Gluck IV void 397dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawArc(BRect rect, const float& angle, const float& span, 398dcaec19cSAlexander von Gluck IV bool filled) 399dcaec19cSAlexander von Gluck IV { 400dcaec19cSAlexander von Gluck IV BRect bounds = rect; 401dcaec19cSAlexander von Gluck IV if (!filled) 402dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 403dcaec19cSAlexander von Gluck IV 404dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 405dcaec19cSAlexander von Gluck IV return; 406dcaec19cSAlexander von Gluck IV 407dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 408dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_ARC : RP_STROKE_ARC); 409dcaec19cSAlexander von Gluck IV message.Add(fToken); 410dcaec19cSAlexander von Gluck IV message.Add(rect); 411dcaec19cSAlexander von Gluck IV message.Add(angle); 412dcaec19cSAlexander von Gluck IV message.Add(span); 413dcaec19cSAlexander von Gluck IV } 414dcaec19cSAlexander von Gluck IV 415dcaec19cSAlexander von Gluck IV void 416dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillArc(BRect rect, const float& angle, const float& span, 417dcaec19cSAlexander von Gluck IV const BGradient& gradient) 418dcaec19cSAlexander von Gluck IV { 419dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 420dcaec19cSAlexander von Gluck IV return; 421dcaec19cSAlexander von Gluck IV 422dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 423dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_ARC_GRADIENT); 424dcaec19cSAlexander von Gluck IV message.Add(fToken); 425dcaec19cSAlexander von Gluck IV message.Add(rect); 426dcaec19cSAlexander von Gluck IV message.Add(angle); 427dcaec19cSAlexander von Gluck IV message.Add(span); 428dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 429dcaec19cSAlexander von Gluck IV } 430dcaec19cSAlexander von Gluck IV 431dcaec19cSAlexander von Gluck IV 432dcaec19cSAlexander von Gluck IV void 433dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawBezier(BPoint* points, bool filled) 434dcaec19cSAlexander von Gluck IV { 435dcaec19cSAlexander von Gluck IV BRect bounds = _BuildBounds(points, 4); 436dcaec19cSAlexander von Gluck IV if (!filled) 437dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 438dcaec19cSAlexander von Gluck IV 439dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 440dcaec19cSAlexander von Gluck IV return; 441dcaec19cSAlexander von Gluck IV 442dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 443dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_BEZIER : RP_STROKE_BEZIER); 444dcaec19cSAlexander von Gluck IV message.Add(fToken); 445dcaec19cSAlexander von Gluck IV message.AddList(points, 4); 446dcaec19cSAlexander von Gluck IV } 447dcaec19cSAlexander von Gluck IV 448dcaec19cSAlexander von Gluck IV 449dcaec19cSAlexander von Gluck IV void 450dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillBezier(BPoint* points, const BGradient& gradient) 451dcaec19cSAlexander von Gluck IV { 452dcaec19cSAlexander von Gluck IV BRect bounds = _BuildBounds(points, 4); 453dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 454dcaec19cSAlexander von Gluck IV return; 455dcaec19cSAlexander von Gluck IV 456dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 457dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_BEZIER_GRADIENT); 458dcaec19cSAlexander von Gluck IV message.Add(fToken); 459dcaec19cSAlexander von Gluck IV message.AddList(points, 4); 460dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 461dcaec19cSAlexander von Gluck IV } 462dcaec19cSAlexander von Gluck IV 463dcaec19cSAlexander von Gluck IV 464dcaec19cSAlexander von Gluck IV void 465dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawEllipse(BRect rect, bool filled) 466dcaec19cSAlexander von Gluck IV { 467dcaec19cSAlexander von Gluck IV BRect bounds = rect; 468dcaec19cSAlexander von Gluck IV if (!filled) 469dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 470dcaec19cSAlexander von Gluck IV 471dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 472dcaec19cSAlexander von Gluck IV return; 473dcaec19cSAlexander von Gluck IV 474dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 475dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_ELLIPSE : RP_STROKE_ELLIPSE); 476dcaec19cSAlexander von Gluck IV message.Add(fToken); 477dcaec19cSAlexander von Gluck IV message.Add(rect); 478dcaec19cSAlexander von Gluck IV } 479dcaec19cSAlexander von Gluck IV 480dcaec19cSAlexander von Gluck IV 481dcaec19cSAlexander von Gluck IV void 482dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillEllipse(BRect rect, const BGradient& gradient) 483dcaec19cSAlexander von Gluck IV { 484dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 485dcaec19cSAlexander von Gluck IV return; 486dcaec19cSAlexander von Gluck IV 487dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 488dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_ELLIPSE_GRADIENT); 489dcaec19cSAlexander von Gluck IV message.Add(fToken); 490dcaec19cSAlexander von Gluck IV message.Add(rect); 491dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 492dcaec19cSAlexander von Gluck IV } 493dcaec19cSAlexander von Gluck IV 494dcaec19cSAlexander von Gluck IV 495dcaec19cSAlexander von Gluck IV void 496dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawPolygon(BPoint* pointList, int32 numPoints, 497dcaec19cSAlexander von Gluck IV BRect bounds, bool filled, bool closed) 498dcaec19cSAlexander von Gluck IV { 499dcaec19cSAlexander von Gluck IV BRect clipBounds = bounds; 500dcaec19cSAlexander von Gluck IV if (!filled) 501dcaec19cSAlexander von Gluck IV clipBounds.InsetBy(fExtendWidth, fExtendWidth); 502dcaec19cSAlexander von Gluck IV 503dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(clipBounds)) 504dcaec19cSAlexander von Gluck IV return; 505dcaec19cSAlexander von Gluck IV 506dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 507dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_POLYGON : RP_STROKE_POLYGON); 508dcaec19cSAlexander von Gluck IV message.Add(fToken); 509dcaec19cSAlexander von Gluck IV message.Add(bounds); 510dcaec19cSAlexander von Gluck IV message.Add(closed); 511dcaec19cSAlexander von Gluck IV message.Add(numPoints); 512dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < numPoints; i++) 513dcaec19cSAlexander von Gluck IV message.Add(pointList[i]); 514dcaec19cSAlexander von Gluck IV } 515dcaec19cSAlexander von Gluck IV 516dcaec19cSAlexander von Gluck IV 517dcaec19cSAlexander von Gluck IV void 518dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillPolygon(BPoint* pointList, int32 numPoints, 519dcaec19cSAlexander von Gluck IV BRect bounds, const BGradient& gradient, bool closed) 520dcaec19cSAlexander von Gluck IV { 521dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 522dcaec19cSAlexander von Gluck IV return; 523dcaec19cSAlexander von Gluck IV 524dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 525dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_POLYGON_GRADIENT); 526dcaec19cSAlexander von Gluck IV message.Add(fToken); 527dcaec19cSAlexander von Gluck IV message.Add(bounds); 528dcaec19cSAlexander von Gluck IV message.Add(closed); 529dcaec19cSAlexander von Gluck IV message.Add(numPoints); 530dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < numPoints; i++) 531dcaec19cSAlexander von Gluck IV message.Add(pointList[i]); 532dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 533dcaec19cSAlexander von Gluck IV } 534dcaec19cSAlexander von Gluck IV 535dcaec19cSAlexander von Gluck IV 536dcaec19cSAlexander von Gluck IV // #pragma mark - rgb_color versions 537dcaec19cSAlexander von Gluck IV 538dcaec19cSAlexander von Gluck IV 539dcaec19cSAlexander von Gluck IV void 540dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokePoint(const BPoint& point, const rgb_color& color) 541dcaec19cSAlexander von Gluck IV { 542dcaec19cSAlexander von Gluck IV BRect bounds(point, point); 543dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 544dcaec19cSAlexander von Gluck IV 545dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 546dcaec19cSAlexander von Gluck IV return; 547dcaec19cSAlexander von Gluck IV 548dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 549dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_POINT_COLOR); 550dcaec19cSAlexander von Gluck IV message.Add(fToken); 551dcaec19cSAlexander von Gluck IV message.Add(point); 552dcaec19cSAlexander von Gluck IV message.Add(color); 553dcaec19cSAlexander von Gluck IV } 554dcaec19cSAlexander von Gluck IV 555dcaec19cSAlexander von Gluck IV 556dcaec19cSAlexander von Gluck IV void 557dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeLine(const BPoint& start, const BPoint& end, 558dcaec19cSAlexander von Gluck IV const rgb_color& color) 559dcaec19cSAlexander von Gluck IV { 560dcaec19cSAlexander von Gluck IV BPoint points[2] = { start, end }; 561dcaec19cSAlexander von Gluck IV BRect bounds = _BuildBounds(points, 2); 562dcaec19cSAlexander von Gluck IV 563dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 564dcaec19cSAlexander von Gluck IV return; 565dcaec19cSAlexander von Gluck IV 566dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 567dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_LINE_1PX_COLOR); 568dcaec19cSAlexander von Gluck IV message.Add(fToken); 569dcaec19cSAlexander von Gluck IV message.AddList(points, 2); 570dcaec19cSAlexander von Gluck IV message.Add(color); 571dcaec19cSAlexander von Gluck IV } 572dcaec19cSAlexander von Gluck IV 573dcaec19cSAlexander von Gluck IV 574dcaec19cSAlexander von Gluck IV void 575dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeRect(BRect rect, const rgb_color &color) 576dcaec19cSAlexander von Gluck IV { 577dcaec19cSAlexander von Gluck IV BRect bounds = rect; 578dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 579dcaec19cSAlexander von Gluck IV 580dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 581dcaec19cSAlexander von Gluck IV return; 582dcaec19cSAlexander von Gluck IV 583dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 584dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_RECT_1PX_COLOR); 585dcaec19cSAlexander von Gluck IV message.Add(fToken); 586dcaec19cSAlexander von Gluck IV message.Add(rect); 587dcaec19cSAlexander von Gluck IV message.Add(color); 588dcaec19cSAlexander von Gluck IV } 589dcaec19cSAlexander von Gluck IV 590dcaec19cSAlexander von Gluck IV 591dcaec19cSAlexander von Gluck IV void 592dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRect(BRect rect, const rgb_color& color) 593dcaec19cSAlexander von Gluck IV { 594dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 595dcaec19cSAlexander von Gluck IV return; 596dcaec19cSAlexander von Gluck IV 597dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 598dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_RECT_COLOR); 599dcaec19cSAlexander von Gluck IV message.Add(fToken); 600dcaec19cSAlexander von Gluck IV message.Add(rect); 601dcaec19cSAlexander von Gluck IV message.Add(color); 602dcaec19cSAlexander von Gluck IV } 603dcaec19cSAlexander von Gluck IV 604dcaec19cSAlexander von Gluck IV 605dcaec19cSAlexander von Gluck IV void 606dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRegion(BRegion& region, const rgb_color& color) 607dcaec19cSAlexander von Gluck IV { 608dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 609dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_REGION_COLOR_NO_CLIPPING); 610dcaec19cSAlexander von Gluck IV message.AddRegion(region); 611dcaec19cSAlexander von Gluck IV message.Add(color); 612dcaec19cSAlexander von Gluck IV } 613dcaec19cSAlexander von Gluck IV 614dcaec19cSAlexander von Gluck IV 615dcaec19cSAlexander von Gluck IV // #pragma mark - DrawState versions 616dcaec19cSAlexander von Gluck IV 617dcaec19cSAlexander von Gluck IV 618dcaec19cSAlexander von Gluck IV void 619dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeRect(BRect rect) 620dcaec19cSAlexander von Gluck IV { 621dcaec19cSAlexander von Gluck IV BRect bounds = rect; 622dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 623dcaec19cSAlexander von Gluck IV 624dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 625dcaec19cSAlexander von Gluck IV return; 626dcaec19cSAlexander von Gluck IV 627dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 628dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_RECT); 629dcaec19cSAlexander von Gluck IV message.Add(fToken); 630dcaec19cSAlexander von Gluck IV message.Add(rect); 631dcaec19cSAlexander von Gluck IV } 632dcaec19cSAlexander von Gluck IV 633dcaec19cSAlexander von Gluck IV 634dcaec19cSAlexander von Gluck IV void 635dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRect(BRect rect) 636dcaec19cSAlexander von Gluck IV { 637dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 638dcaec19cSAlexander von Gluck IV return; 639dcaec19cSAlexander von Gluck IV 640dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 641dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_RECT); 642dcaec19cSAlexander von Gluck IV message.Add(fToken); 643dcaec19cSAlexander von Gluck IV message.Add(rect); 644dcaec19cSAlexander von Gluck IV } 645dcaec19cSAlexander von Gluck IV 646dcaec19cSAlexander von Gluck IV 647dcaec19cSAlexander von Gluck IV void 648dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRect(BRect rect, const BGradient& gradient) 649dcaec19cSAlexander von Gluck IV { 650dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 651dcaec19cSAlexander von Gluck IV return; 652dcaec19cSAlexander von Gluck IV 653dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 654dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_RECT_GRADIENT); 655dcaec19cSAlexander von Gluck IV message.Add(fToken); 656dcaec19cSAlexander von Gluck IV message.Add(rect); 657dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 658dcaec19cSAlexander von Gluck IV } 659dcaec19cSAlexander von Gluck IV 660dcaec19cSAlexander von Gluck IV 661dcaec19cSAlexander von Gluck IV void 662dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRegion(BRegion& region) 663dcaec19cSAlexander von Gluck IV { 664dcaec19cSAlexander von Gluck IV BRegion clippedRegion = region; 665dcaec19cSAlexander von Gluck IV clippedRegion.IntersectWith(&fClippingRegion); 666dcaec19cSAlexander von Gluck IV if (clippedRegion.CountRects() == 0) 667dcaec19cSAlexander von Gluck IV return; 668dcaec19cSAlexander von Gluck IV 669dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 670dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_REGION); 671dcaec19cSAlexander von Gluck IV message.Add(fToken); 672dcaec19cSAlexander von Gluck IV message.AddRegion(clippedRegion.CountRects() < region.CountRects() 673dcaec19cSAlexander von Gluck IV ? clippedRegion : region); 674dcaec19cSAlexander von Gluck IV } 675dcaec19cSAlexander von Gluck IV 676dcaec19cSAlexander von Gluck IV 677dcaec19cSAlexander von Gluck IV void 678dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRegion(BRegion& region, const BGradient& gradient) 679dcaec19cSAlexander von Gluck IV { 680dcaec19cSAlexander von Gluck IV BRegion clippedRegion = region; 681dcaec19cSAlexander von Gluck IV clippedRegion.IntersectWith(&fClippingRegion); 682dcaec19cSAlexander von Gluck IV if (clippedRegion.CountRects() == 0) 683dcaec19cSAlexander von Gluck IV return; 684dcaec19cSAlexander von Gluck IV 685dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 686dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_REGION_GRADIENT); 687dcaec19cSAlexander von Gluck IV message.Add(fToken); 688dcaec19cSAlexander von Gluck IV message.AddRegion(clippedRegion.CountRects() < region.CountRects() 689dcaec19cSAlexander von Gluck IV ? clippedRegion : region); 690dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 691dcaec19cSAlexander von Gluck IV } 692dcaec19cSAlexander von Gluck IV 693dcaec19cSAlexander von Gluck IV 694dcaec19cSAlexander von Gluck IV void 695dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawRoundRect(BRect rect, float xRadius, float yRadius, 696dcaec19cSAlexander von Gluck IV bool filled) 697dcaec19cSAlexander von Gluck IV { 698dcaec19cSAlexander von Gluck IV BRect bounds = rect; 699dcaec19cSAlexander von Gluck IV if (!filled) 700dcaec19cSAlexander von Gluck IV bounds.InsetBy(fExtendWidth, fExtendWidth); 701dcaec19cSAlexander von Gluck IV 702dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 703dcaec19cSAlexander von Gluck IV return; 704dcaec19cSAlexander von Gluck IV 705dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 706dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_ROUND_RECT : RP_STROKE_ROUND_RECT); 707dcaec19cSAlexander von Gluck IV message.Add(fToken); 708dcaec19cSAlexander von Gluck IV message.Add(rect); 709dcaec19cSAlexander von Gluck IV message.Add(xRadius); 710dcaec19cSAlexander von Gluck IV message.Add(yRadius); 711dcaec19cSAlexander von Gluck IV } 712dcaec19cSAlexander von Gluck IV 713dcaec19cSAlexander von Gluck IV 714dcaec19cSAlexander von Gluck IV void 715dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillRoundRect(BRect rect, float xRadius, float yRadius, 716dcaec19cSAlexander von Gluck IV const BGradient& gradient) 717dcaec19cSAlexander von Gluck IV { 718dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(rect)) 719dcaec19cSAlexander von Gluck IV return; 720dcaec19cSAlexander von Gluck IV 721dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 722dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_ROUND_RECT_GRADIENT); 723dcaec19cSAlexander von Gluck IV message.Add(fToken); 724dcaec19cSAlexander von Gluck IV message.Add(rect); 725dcaec19cSAlexander von Gluck IV message.Add(xRadius); 726dcaec19cSAlexander von Gluck IV message.Add(yRadius); 727dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 728dcaec19cSAlexander von Gluck IV } 729dcaec19cSAlexander von Gluck IV 730dcaec19cSAlexander von Gluck IV 731dcaec19cSAlexander von Gluck IV void 732dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawShape(const BRect& bounds, int32 opCount, 733dcaec19cSAlexander von Gluck IV const uint32* opList, int32 pointCount, const BPoint* pointList, 734dcaec19cSAlexander von Gluck IV bool filled, const BPoint& viewToScreenOffset, float viewScale) 735dcaec19cSAlexander von Gluck IV { 736dcaec19cSAlexander von Gluck IV BRect clipBounds = bounds; 737dcaec19cSAlexander von Gluck IV if (!filled) 738dcaec19cSAlexander von Gluck IV clipBounds.InsetBy(fExtendWidth, fExtendWidth); 739dcaec19cSAlexander von Gluck IV 740dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(clipBounds)) 741dcaec19cSAlexander von Gluck IV return; 742dcaec19cSAlexander von Gluck IV 743dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 744dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_SHAPE : RP_STROKE_SHAPE); 745dcaec19cSAlexander von Gluck IV message.Add(fToken); 746dcaec19cSAlexander von Gluck IV message.Add(bounds); 747dcaec19cSAlexander von Gluck IV message.Add(opCount); 748dcaec19cSAlexander von Gluck IV message.AddList(opList, opCount); 749dcaec19cSAlexander von Gluck IV message.Add(pointCount); 750dcaec19cSAlexander von Gluck IV message.AddList(pointList, pointCount); 751dcaec19cSAlexander von Gluck IV message.Add(viewToScreenOffset); 752dcaec19cSAlexander von Gluck IV message.Add(viewScale); 753dcaec19cSAlexander von Gluck IV } 754dcaec19cSAlexander von Gluck IV 755dcaec19cSAlexander von Gluck IV 756dcaec19cSAlexander von Gluck IV void 757dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillShape(const BRect& bounds, int32 opCount, 758dcaec19cSAlexander von Gluck IV const uint32* opList, int32 pointCount, const BPoint* pointList, 759dcaec19cSAlexander von Gluck IV const BGradient& gradient, const BPoint& viewToScreenOffset, 760dcaec19cSAlexander von Gluck IV float viewScale) 761dcaec19cSAlexander von Gluck IV { 762dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 763dcaec19cSAlexander von Gluck IV return; 764dcaec19cSAlexander von Gluck IV 765dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 766dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_SHAPE_GRADIENT); 767dcaec19cSAlexander von Gluck IV message.Add(fToken); 768dcaec19cSAlexander von Gluck IV message.Add(bounds); 769dcaec19cSAlexander von Gluck IV message.Add(opCount); 770dcaec19cSAlexander von Gluck IV message.AddList(opList, opCount); 771dcaec19cSAlexander von Gluck IV message.Add(pointCount); 772dcaec19cSAlexander von Gluck IV message.AddList(pointList, pointCount); 773dcaec19cSAlexander von Gluck IV message.Add(viewToScreenOffset); 774dcaec19cSAlexander von Gluck IV message.Add(viewScale); 775df55bcf5SMichael Lotz message.AddGradient(gradient); 776dcaec19cSAlexander von Gluck IV } 777dcaec19cSAlexander von Gluck IV 778dcaec19cSAlexander von Gluck IV 779dcaec19cSAlexander von Gluck IV void 780dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawTriangle(BPoint* points, const BRect& bounds, 781dcaec19cSAlexander von Gluck IV bool filled) 782dcaec19cSAlexander von Gluck IV { 783dcaec19cSAlexander von Gluck IV BRect clipBounds = bounds; 784dcaec19cSAlexander von Gluck IV if (!filled) 785dcaec19cSAlexander von Gluck IV clipBounds.InsetBy(fExtendWidth, fExtendWidth); 786dcaec19cSAlexander von Gluck IV 787dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(clipBounds)) 788dcaec19cSAlexander von Gluck IV return; 789dcaec19cSAlexander von Gluck IV 790dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 791dcaec19cSAlexander von Gluck IV message.Start(filled ? RP_FILL_TRIANGLE : RP_STROKE_TRIANGLE); 792dcaec19cSAlexander von Gluck IV message.Add(fToken); 793dcaec19cSAlexander von Gluck IV message.AddList(points, 3); 794dcaec19cSAlexander von Gluck IV message.Add(bounds); 795dcaec19cSAlexander von Gluck IV } 796dcaec19cSAlexander von Gluck IV 797dcaec19cSAlexander von Gluck IV 798dcaec19cSAlexander von Gluck IV void 799dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::FillTriangle(BPoint* points, const BRect& bounds, 800dcaec19cSAlexander von Gluck IV const BGradient& gradient) 801dcaec19cSAlexander von Gluck IV { 802dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 803dcaec19cSAlexander von Gluck IV return; 804dcaec19cSAlexander von Gluck IV 805dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 806dcaec19cSAlexander von Gluck IV message.Start(RP_FILL_TRIANGLE_GRADIENT); 807dcaec19cSAlexander von Gluck IV message.Add(fToken); 8080863572dSMichael Lotz message.AddList(points, 3); 809dcaec19cSAlexander von Gluck IV message.Add(bounds); 810dcaec19cSAlexander von Gluck IV message.AddGradient(gradient); 811dcaec19cSAlexander von Gluck IV } 812dcaec19cSAlexander von Gluck IV 813dcaec19cSAlexander von Gluck IV 814dcaec19cSAlexander von Gluck IV void 815dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeLine(const BPoint &start, const BPoint &end) 816dcaec19cSAlexander von Gluck IV { 817dcaec19cSAlexander von Gluck IV BPoint points[2] = { start, end }; 818dcaec19cSAlexander von Gluck IV BRect bounds = _BuildBounds(points, 2); 819dcaec19cSAlexander von Gluck IV 820dcaec19cSAlexander von Gluck IV if (!fClippingRegion.Intersects(bounds)) 821dcaec19cSAlexander von Gluck IV return; 822dcaec19cSAlexander von Gluck IV 823dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 824dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_LINE); 825dcaec19cSAlexander von Gluck IV message.Add(fToken); 826dcaec19cSAlexander von Gluck IV message.AddList(points, 2); 827dcaec19cSAlexander von Gluck IV } 828dcaec19cSAlexander von Gluck IV 829dcaec19cSAlexander von Gluck IV 830dcaec19cSAlexander von Gluck IV void 831dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StrokeLineArray(int32 numLines, 832dcaec19cSAlexander von Gluck IV const ViewLineArrayInfo *lineData) 833dcaec19cSAlexander von Gluck IV { 834dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 835dcaec19cSAlexander von Gluck IV message.Start(RP_STROKE_LINE_ARRAY); 836dcaec19cSAlexander von Gluck IV message.Add(fToken); 837dcaec19cSAlexander von Gluck IV message.Add(numLines); 838dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < numLines; i++) 839dcaec19cSAlexander von Gluck IV message.AddArrayLine(lineData[i]); 840dcaec19cSAlexander von Gluck IV } 841dcaec19cSAlexander von Gluck IV 842dcaec19cSAlexander von Gluck IV 843dcaec19cSAlexander von Gluck IV // #pragma mark - string functions 844dcaec19cSAlexander von Gluck IV 845dcaec19cSAlexander von Gluck IV 846dcaec19cSAlexander von Gluck IV BPoint 847dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawString(const char* string, int32 length, 848dcaec19cSAlexander von Gluck IV const BPoint& point, escapement_delta* delta) 849dcaec19cSAlexander von Gluck IV { 850dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 851dcaec19cSAlexander von Gluck IV 852dcaec19cSAlexander von Gluck IV message.Start(RP_DRAW_STRING); 853dcaec19cSAlexander von Gluck IV message.Add(fToken); 854dcaec19cSAlexander von Gluck IV message.Add(point); 855dcaec19cSAlexander von Gluck IV message.AddString(string, length); 856dcaec19cSAlexander von Gluck IV message.Add(delta != NULL); 857dcaec19cSAlexander von Gluck IV if (delta != NULL) 858dcaec19cSAlexander von Gluck IV message.AddList(delta, length); 859dcaec19cSAlexander von Gluck IV 860dcaec19cSAlexander von Gluck IV status_t result = _AddCallback(); 861dcaec19cSAlexander von Gluck IV if (message.Flush() != B_OK) 862dcaec19cSAlexander von Gluck IV return point; 863dcaec19cSAlexander von Gluck IV 864dcaec19cSAlexander von Gluck IV if (result != B_OK) 865dcaec19cSAlexander von Gluck IV return point; 866dcaec19cSAlexander von Gluck IV 867dcaec19cSAlexander von Gluck IV do { 868dcaec19cSAlexander von Gluck IV result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 869dcaec19cSAlexander von Gluck IV 1 * 1000 * 1000); 870dcaec19cSAlexander von Gluck IV } while (result == B_INTERRUPTED); 871dcaec19cSAlexander von Gluck IV 872dcaec19cSAlexander von Gluck IV if (result != B_OK) 873dcaec19cSAlexander von Gluck IV return point; 874dcaec19cSAlexander von Gluck IV 875dcaec19cSAlexander von Gluck IV return fDrawStringResult; 876dcaec19cSAlexander von Gluck IV } 877dcaec19cSAlexander von Gluck IV 878dcaec19cSAlexander von Gluck IV 879dcaec19cSAlexander von Gluck IV BPoint 880dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::DrawString(const char* string, int32 length, 881dcaec19cSAlexander von Gluck IV const BPoint* offsets) 882dcaec19cSAlexander von Gluck IV { 883dcaec19cSAlexander von Gluck IV // Guaranteed to have at least one point. 884dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 885dcaec19cSAlexander von Gluck IV 886dcaec19cSAlexander von Gluck IV message.Start(RP_DRAW_STRING_WITH_OFFSETS); 887dcaec19cSAlexander von Gluck IV message.Add(fToken); 888dcaec19cSAlexander von Gluck IV message.AddString(string, length); 889dcaec19cSAlexander von Gluck IV message.AddList(offsets, UTF8CountChars(string, length)); 890dcaec19cSAlexander von Gluck IV 891dcaec19cSAlexander von Gluck IV status_t result = _AddCallback(); 892dcaec19cSAlexander von Gluck IV if (message.Flush() != B_OK) 893dcaec19cSAlexander von Gluck IV return offsets[0]; 894dcaec19cSAlexander von Gluck IV 895dcaec19cSAlexander von Gluck IV if (result != B_OK) 896dcaec19cSAlexander von Gluck IV return offsets[0]; 897dcaec19cSAlexander von Gluck IV 898dcaec19cSAlexander von Gluck IV do { 899dcaec19cSAlexander von Gluck IV result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 900dcaec19cSAlexander von Gluck IV 1 * 1000 * 1000); 901dcaec19cSAlexander von Gluck IV } while (result == B_INTERRUPTED); 902dcaec19cSAlexander von Gluck IV 903dcaec19cSAlexander von Gluck IV if (result != B_OK) 904dcaec19cSAlexander von Gluck IV return offsets[0]; 905dcaec19cSAlexander von Gluck IV 906dcaec19cSAlexander von Gluck IV return fDrawStringResult; 907dcaec19cSAlexander von Gluck IV } 908dcaec19cSAlexander von Gluck IV 909dcaec19cSAlexander von Gluck IV 910dcaec19cSAlexander von Gluck IV float 911dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::StringWidth(const char* string, int32 length, 912dcaec19cSAlexander von Gluck IV escapement_delta* delta) 913dcaec19cSAlexander von Gluck IV { 9145fb27ee2SMichael Lotz // TODO: Decide if really needed. 9155fb27ee2SMichael Lotz 9165fb27ee2SMichael Lotz while (true) { 9175fb27ee2SMichael Lotz if (_AddCallback() != B_OK) 9185fb27ee2SMichael Lotz break; 9195fb27ee2SMichael Lotz 9205fb27ee2SMichael Lotz RemoteMessage message(NULL, fHWInterface->SendBuffer()); 9215fb27ee2SMichael Lotz 9225fb27ee2SMichael Lotz message.Start(RP_STRING_WIDTH); 9235fb27ee2SMichael Lotz message.Add(fToken); 9245fb27ee2SMichael Lotz message.AddString(string, length); 9255fb27ee2SMichael Lotz // TODO: Support escapement delta. 9265fb27ee2SMichael Lotz 9275fb27ee2SMichael Lotz if (message.Flush() != B_OK) 9285fb27ee2SMichael Lotz break; 9295fb27ee2SMichael Lotz 9305fb27ee2SMichael Lotz status_t result; 9315fb27ee2SMichael Lotz do { 9325fb27ee2SMichael Lotz result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 9335fb27ee2SMichael Lotz 1 * 1000 * 1000); 9345fb27ee2SMichael Lotz } while (result == B_INTERRUPTED); 9355fb27ee2SMichael Lotz 9365fb27ee2SMichael Lotz if (result != B_OK) 9375fb27ee2SMichael Lotz break; 9385fb27ee2SMichael Lotz 9395fb27ee2SMichael Lotz return fStringWidthResult; 9405fb27ee2SMichael Lotz } 9415fb27ee2SMichael Lotz 9425fb27ee2SMichael Lotz // Fall back to local calculation. 943dcaec19cSAlexander von Gluck IV return fState.Font().StringWidth(string, length, delta); 944dcaec19cSAlexander von Gluck IV } 945dcaec19cSAlexander von Gluck IV 946dcaec19cSAlexander von Gluck IV 947dcaec19cSAlexander von Gluck IV // #pragma mark - 948dcaec19cSAlexander von Gluck IV 949dcaec19cSAlexander von Gluck IV 950dcaec19cSAlexander von Gluck IV status_t 951dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::ReadBitmap(ServerBitmap* bitmap, bool drawCursor, 952dcaec19cSAlexander von Gluck IV BRect bounds) 953dcaec19cSAlexander von Gluck IV { 954dcaec19cSAlexander von Gluck IV if (_AddCallback() != B_OK) 955dcaec19cSAlexander von Gluck IV return B_UNSUPPORTED; 956dcaec19cSAlexander von Gluck IV 957dcaec19cSAlexander von Gluck IV RemoteMessage message(NULL, fHWInterface->SendBuffer()); 958dcaec19cSAlexander von Gluck IV 959dcaec19cSAlexander von Gluck IV message.Start(RP_READ_BITMAP); 960dcaec19cSAlexander von Gluck IV message.Add(fToken); 961dcaec19cSAlexander von Gluck IV message.Add(bounds); 962dcaec19cSAlexander von Gluck IV message.Add(drawCursor); 963dcaec19cSAlexander von Gluck IV if (message.Flush() != B_OK) 964dcaec19cSAlexander von Gluck IV return B_UNSUPPORTED; 965dcaec19cSAlexander von Gluck IV 966dcaec19cSAlexander von Gluck IV status_t result; 967dcaec19cSAlexander von Gluck IV do { 968dcaec19cSAlexander von Gluck IV result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 96960882f20SMichael Lotz 10 * 1000 * 1000); 970dcaec19cSAlexander von Gluck IV } while (result == B_INTERRUPTED); 971dcaec19cSAlexander von Gluck IV 972dcaec19cSAlexander von Gluck IV if (result != B_OK) 973dcaec19cSAlexander von Gluck IV return result; 974dcaec19cSAlexander von Gluck IV 975dcaec19cSAlexander von Gluck IV BBitmap* read = fReadBitmapResult; 976dcaec19cSAlexander von Gluck IV if (read == NULL) 977dcaec19cSAlexander von Gluck IV return B_UNSUPPORTED; 978dcaec19cSAlexander von Gluck IV 979dcaec19cSAlexander von Gluck IV result = bitmap->ImportBits(read->Bits(), read->BitsLength(), 980dcaec19cSAlexander von Gluck IV read->BytesPerRow(), read->ColorSpace()); 981dcaec19cSAlexander von Gluck IV delete read; 982dcaec19cSAlexander von Gluck IV return result; 983dcaec19cSAlexander von Gluck IV } 984dcaec19cSAlexander von Gluck IV 985dcaec19cSAlexander von Gluck IV 986dcaec19cSAlexander von Gluck IV // #pragma mark - 987dcaec19cSAlexander von Gluck IV 988dcaec19cSAlexander von Gluck IV 989dcaec19cSAlexander von Gluck IV status_t 990dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::_AddCallback() 991dcaec19cSAlexander von Gluck IV { 992dcaec19cSAlexander von Gluck IV if (fCallbackAdded) 993dcaec19cSAlexander von Gluck IV return B_OK; 994dcaec19cSAlexander von Gluck IV 995dcaec19cSAlexander von Gluck IV if (fResultNotify < 0) 996dcaec19cSAlexander von Gluck IV fResultNotify = create_sem(0, "drawing engine result"); 997dcaec19cSAlexander von Gluck IV if (fResultNotify < 0) 998dcaec19cSAlexander von Gluck IV return fResultNotify; 999dcaec19cSAlexander von Gluck IV 1000dcaec19cSAlexander von Gluck IV status_t result = fHWInterface->AddCallback(fToken, &_DrawingEngineResult, 1001dcaec19cSAlexander von Gluck IV this); 1002dcaec19cSAlexander von Gluck IV 1003dcaec19cSAlexander von Gluck IV fCallbackAdded = result == B_OK; 1004dcaec19cSAlexander von Gluck IV return result; 1005dcaec19cSAlexander von Gluck IV } 1006dcaec19cSAlexander von Gluck IV 1007dcaec19cSAlexander von Gluck IV 1008dcaec19cSAlexander von Gluck IV bool 1009dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::_DrawingEngineResult(void* cookie, RemoteMessage& message) 1010dcaec19cSAlexander von Gluck IV { 1011dcaec19cSAlexander von Gluck IV RemoteDrawingEngine* engine = (RemoteDrawingEngine*)cookie; 1012dcaec19cSAlexander von Gluck IV 1013dcaec19cSAlexander von Gluck IV switch (message.Code()) { 1014dcaec19cSAlexander von Gluck IV case RP_DRAW_STRING_RESULT: 10154d9e21b8SMichael Lotz { 10164d9e21b8SMichael Lotz status_t result = message.Read(engine->fDrawStringResult); 10174d9e21b8SMichael Lotz if (result != B_OK) { 10184d9e21b8SMichael Lotz TRACE_ERROR("failed to read draw string result: %s\n", 10194d9e21b8SMichael Lotz strerror(result)); 1020dcaec19cSAlexander von Gluck IV return false; 10214d9e21b8SMichael Lotz } 10224d9e21b8SMichael Lotz 1023dcaec19cSAlexander von Gluck IV break; 10244d9e21b8SMichael Lotz } 1025dcaec19cSAlexander von Gluck IV 1026dcaec19cSAlexander von Gluck IV case RP_STRING_WIDTH_RESULT: 10274d9e21b8SMichael Lotz { 10284d9e21b8SMichael Lotz status_t result = message.Read(engine->fStringWidthResult); 10294d9e21b8SMichael Lotz if (result != B_OK) { 10304d9e21b8SMichael Lotz TRACE_ERROR("failed to read string width result: %s\n", 10314d9e21b8SMichael Lotz strerror(result)); 1032dcaec19cSAlexander von Gluck IV return false; 10334d9e21b8SMichael Lotz } 10344d9e21b8SMichael Lotz 1035dcaec19cSAlexander von Gluck IV break; 10364d9e21b8SMichael Lotz } 1037dcaec19cSAlexander von Gluck IV 1038dcaec19cSAlexander von Gluck IV case RP_READ_BITMAP_RESULT: 10394d9e21b8SMichael Lotz { 10404d9e21b8SMichael Lotz status_t result = message.ReadBitmap(&engine->fReadBitmapResult); 10414d9e21b8SMichael Lotz if (result != B_OK) { 10424d9e21b8SMichael Lotz TRACE_ERROR("failed to read bitmap of read bitmap result: %s\n", 10434d9e21b8SMichael Lotz strerror(result)); 1044dcaec19cSAlexander von Gluck IV return false; 10454d9e21b8SMichael Lotz } 10464d9e21b8SMichael Lotz 1047dcaec19cSAlexander von Gluck IV break; 10484d9e21b8SMichael Lotz } 1049dcaec19cSAlexander von Gluck IV 1050dcaec19cSAlexander von Gluck IV default: 1051dcaec19cSAlexander von Gluck IV return false; 1052dcaec19cSAlexander von Gluck IV } 1053dcaec19cSAlexander von Gluck IV 1054dcaec19cSAlexander von Gluck IV release_sem(engine->fResultNotify); 1055dcaec19cSAlexander von Gluck IV return true; 1056dcaec19cSAlexander von Gluck IV } 1057dcaec19cSAlexander von Gluck IV 1058dcaec19cSAlexander von Gluck IV 1059dcaec19cSAlexander von Gluck IV BRect 1060dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::_BuildBounds(BPoint* points, int32 pointCount) 1061dcaec19cSAlexander von Gluck IV { 1062dcaec19cSAlexander von Gluck IV BRect bounds(1000000, 1000000, 0, 0); 1063dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < pointCount; i++) { 1064dcaec19cSAlexander von Gluck IV bounds.left = min_c(bounds.left, points[i].x); 1065dcaec19cSAlexander von Gluck IV bounds.top = min_c(bounds.top, points[i].y); 1066dcaec19cSAlexander von Gluck IV bounds.right = max_c(bounds.right, points[i].x); 1067dcaec19cSAlexander von Gluck IV bounds.bottom = max_c(bounds.bottom, points[i].y); 1068dcaec19cSAlexander von Gluck IV } 1069dcaec19cSAlexander von Gluck IV 1070dcaec19cSAlexander von Gluck IV return bounds; 1071dcaec19cSAlexander von Gluck IV } 1072dcaec19cSAlexander von Gluck IV 1073dcaec19cSAlexander von Gluck IV 1074dcaec19cSAlexander von Gluck IV status_t 1075dcaec19cSAlexander von Gluck IV RemoteDrawingEngine::_ExtractBitmapRegions(ServerBitmap& bitmap, uint32 options, 1076dcaec19cSAlexander von Gluck IV const BRect& bitmapRect, const BRect& viewRect, double xScale, 1077dcaec19cSAlexander von Gluck IV double yScale, BRegion& region, UtilityBitmap**& bitmaps) 1078dcaec19cSAlexander von Gluck IV { 1079dcaec19cSAlexander von Gluck IV int32 rectCount = region.CountRects(); 1080dcaec19cSAlexander von Gluck IV bitmaps = (UtilityBitmap**)malloc(rectCount * sizeof(UtilityBitmap*)); 1081dcaec19cSAlexander von Gluck IV if (bitmaps == NULL) 1082dcaec19cSAlexander von Gluck IV return B_NO_MEMORY; 1083dcaec19cSAlexander von Gluck IV 1084dcaec19cSAlexander von Gluck IV for (int32 i = 0; i < rectCount; i++) { 1085dcaec19cSAlexander von Gluck IV BRect sourceRect = region.RectAt(i).OffsetByCopy(-viewRect.LeftTop()); 1086dcaec19cSAlexander von Gluck IV int32 targetWidth = (int32)(sourceRect.Width() + 1.5); 1087dcaec19cSAlexander von Gluck IV int32 targetHeight = (int32)(sourceRect.Height() + 1.5); 1088dcaec19cSAlexander von Gluck IV 1089dcaec19cSAlexander von Gluck IV if (xScale != 1.0) { 1090dcaec19cSAlexander von Gluck IV sourceRect.left = (int32)(sourceRect.left * xScale + 0.5); 1091dcaec19cSAlexander von Gluck IV sourceRect.right = (int32)(sourceRect.right * xScale + 0.5); 1092dcaec19cSAlexander von Gluck IV if (xScale < 1.0) 1093dcaec19cSAlexander von Gluck IV targetWidth = (int32)(sourceRect.Width() + 1.5); 1094dcaec19cSAlexander von Gluck IV } 1095dcaec19cSAlexander von Gluck IV 1096dcaec19cSAlexander von Gluck IV if (yScale != 1.0) { 1097dcaec19cSAlexander von Gluck IV sourceRect.top = (int32)(sourceRect.top * yScale + 0.5); 1098dcaec19cSAlexander von Gluck IV sourceRect.bottom = (int32)(sourceRect.bottom * yScale + 0.5); 1099dcaec19cSAlexander von Gluck IV if (yScale < 1.0) 1100dcaec19cSAlexander von Gluck IV targetHeight = (int32)(sourceRect.Height() + 1.5); 1101dcaec19cSAlexander von Gluck IV } 1102dcaec19cSAlexander von Gluck IV 1103dcaec19cSAlexander von Gluck IV sourceRect.OffsetBy(bitmapRect.LeftTop()); 1104dcaec19cSAlexander von Gluck IV // sourceRect is now the part of the bitmap we want copied 1105dcaec19cSAlexander von Gluck IV 1106dcaec19cSAlexander von Gluck IV status_t result = B_OK; 1107dcaec19cSAlexander von Gluck IV if ((xScale > 1.0 || yScale > 1.0) 1108dcaec19cSAlexander von Gluck IV && (targetWidth * targetHeight < (int32)(sourceRect.Width() + 1.5) 1109dcaec19cSAlexander von Gluck IV * (int32)(sourceRect.Height() + 1.5))) { 1110dcaec19cSAlexander von Gluck IV // the target bitmap is smaller than the source, scale it locally 1111dcaec19cSAlexander von Gluck IV // and send over the smaller version to avoid sending any extra data 1112dcaec19cSAlexander von Gluck IV if (fBitmapDrawingEngine == NULL) { 1113dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine 1114dcaec19cSAlexander von Gluck IV = new(std::nothrow) BitmapDrawingEngine(B_RGBA32); 1115dcaec19cSAlexander von Gluck IV if (fBitmapDrawingEngine == NULL) 1116dcaec19cSAlexander von Gluck IV result = B_NO_MEMORY; 1117dcaec19cSAlexander von Gluck IV } 1118dcaec19cSAlexander von Gluck IV 1119dcaec19cSAlexander von Gluck IV if (result == B_OK) { 1120dcaec19cSAlexander von Gluck IV result = fBitmapDrawingEngine->SetSize(targetWidth, 1121dcaec19cSAlexander von Gluck IV targetHeight); 1122dcaec19cSAlexander von Gluck IV } 1123dcaec19cSAlexander von Gluck IV 1124dcaec19cSAlexander von Gluck IV if (result == B_OK) { 1125dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine->SetDrawingMode(B_OP_COPY); 1126dcaec19cSAlexander von Gluck IV 1127dcaec19cSAlexander von Gluck IV switch (bitmap.ColorSpace()) { 1128dcaec19cSAlexander von Gluck IV case B_RGBA32: 1129dcaec19cSAlexander von Gluck IV case B_RGBA32_BIG: 1130dcaec19cSAlexander von Gluck IV case B_RGBA15: 1131dcaec19cSAlexander von Gluck IV case B_RGBA15_BIG: 1132dcaec19cSAlexander von Gluck IV break; 1133dcaec19cSAlexander von Gluck IV 1134dcaec19cSAlexander von Gluck IV default: 1135dcaec19cSAlexander von Gluck IV { 1136dcaec19cSAlexander von Gluck IV // we need to clear the background if there may be 1137dcaec19cSAlexander von Gluck IV // transparency through transparent magic (we use 1138dcaec19cSAlexander von Gluck IV // B_OP_COPY when we draw alpha enabled bitmaps, so we 1139dcaec19cSAlexander von Gluck IV // don't need to clear there) 1140dcaec19cSAlexander von Gluck IV // TODO: this is not actually correct, as we're going to 1141dcaec19cSAlexander von Gluck IV // loose the transparency with the conversion to the 1142dcaec19cSAlexander von Gluck IV // original non-alpha colorspace happening in 1143dcaec19cSAlexander von Gluck IV // ExportToBitmap 1144dcaec19cSAlexander von Gluck IV rgb_color background = { 0, 0, 0, 0 }; 1145dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine->FillRect( 1146dcaec19cSAlexander von Gluck IV BRect(0, 0, targetWidth - 1, targetHeight -1), 1147dcaec19cSAlexander von Gluck IV background); 1148dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine->SetDrawingMode(B_OP_OVER); 1149dcaec19cSAlexander von Gluck IV break; 1150dcaec19cSAlexander von Gluck IV } 1151dcaec19cSAlexander von Gluck IV } 1152dcaec19cSAlexander von Gluck IV 1153dcaec19cSAlexander von Gluck IV fBitmapDrawingEngine->DrawBitmap(&bitmap, sourceRect, 1154dcaec19cSAlexander von Gluck IV BRect(0, 0, targetWidth - 1, targetHeight - 1), options); 1155dcaec19cSAlexander von Gluck IV bitmaps[i] = fBitmapDrawingEngine->ExportToBitmap(targetWidth, 1156dcaec19cSAlexander von Gluck IV targetHeight, bitmap.ColorSpace()); 1157dcaec19cSAlexander von Gluck IV if (bitmaps[i] == NULL) 1158dcaec19cSAlexander von Gluck IV result = B_NO_MEMORY; 1159dcaec19cSAlexander von Gluck IV } 1160dcaec19cSAlexander von Gluck IV } else { 1161dcaec19cSAlexander von Gluck IV // source is smaller or equal target, extract the relevant rects 1162dcaec19cSAlexander von Gluck IV // directly without any scaling and conversion 1163dcaec19cSAlexander von Gluck IV targetWidth = (int32)(sourceRect.Width() + 1.5); 1164dcaec19cSAlexander von Gluck IV targetHeight = (int32)(sourceRect.Height() + 1.5); 1165dcaec19cSAlexander von Gluck IV 1166dcaec19cSAlexander von Gluck IV bitmaps[i] = new(std::nothrow) UtilityBitmap( 1167dcaec19cSAlexander von Gluck IV BRect(0, 0, targetWidth - 1, targetHeight - 1), 1168dcaec19cSAlexander von Gluck IV bitmap.ColorSpace(), 0); 1169c347a4d4SMurai Takashi if (bitmaps[i] == NULL) { 1170dcaec19cSAlexander von Gluck IV result = B_NO_MEMORY; 1171c347a4d4SMurai Takashi } else { 1172c347a4d4SMurai Takashi result = bitmaps[i]->ImportBits(bitmap.Bits(), 1173c347a4d4SMurai Takashi bitmap.BitsLength(), bitmap.BytesPerRow(), 1174c347a4d4SMurai Takashi bitmap.ColorSpace(), sourceRect.LeftTop(), 1175dcaec19cSAlexander von Gluck IV BPoint(0, 0), targetWidth, targetHeight); 1176c347a4d4SMurai Takashi if (result != B_OK) { 1177dcaec19cSAlexander von Gluck IV delete bitmaps[i]; 1178c347a4d4SMurai Takashi bitmaps[i] = NULL; 1179c347a4d4SMurai Takashi } 1180c347a4d4SMurai Takashi } 1181dcaec19cSAlexander von Gluck IV } 1182dcaec19cSAlexander von Gluck IV 1183dcaec19cSAlexander von Gluck IV if (result != B_OK) { 1184dcaec19cSAlexander von Gluck IV for (int32 j = 0; j < i; j++) 1185dcaec19cSAlexander von Gluck IV delete bitmaps[j]; 1186dcaec19cSAlexander von Gluck IV free(bitmaps); 1187dcaec19cSAlexander von Gluck IV return result; 1188dcaec19cSAlexander von Gluck IV } 1189dcaec19cSAlexander von Gluck IV } 1190dcaec19cSAlexander von Gluck IV 1191dcaec19cSAlexander von Gluck IV return B_OK; 1192dcaec19cSAlexander von Gluck IV } 1193