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