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