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