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