2 * Copyright 2001-2015, Haiku.
3 * Distributed under the terms of the MIT License.
6 * Marc Flerackers (mflerackers@androme.be)
7 * Stefano Ceccherini (stefano.ceccherini@gmail.com)
8 * Marcus Overhagen <marcus@overhagen.de>
9 * Julian Harnath <julian.harnath@rwth-aachen.de>
12 #include "ServerPicture.h"
18 #include "AlphaMask.h"
19 #include "DrawingEngine.h"
20 #include "DrawState.h"
21 #include "FontManager.h"
23 #include "ServerApp.h"
24 #include "ServerBitmap.h"
25 #include "ServerFont.h"
26 #include "ServerTokenSpace.h"
30 #include <LinkReceiver.h>
31 #include <OffsetFile.h>
32 #include <ObjectListPrivate.h>
33 #include <PicturePlayer.h>
34 #include <PictureProtocol.h>
36 #include <ServerProtocol.h>
37 #include <ShapePrivate.h>
48 class ShapePainter
: public BShapeIterator
{
50 ShapePainter(Canvas
* canvas
);
51 virtual ~ShapePainter();
53 status_t
Iterate(const BShape
* shape
);
55 virtual status_t
IterateMoveTo(BPoint
* point
);
56 virtual status_t
IterateLineTo(int32 lineCount
, BPoint
* linePts
);
57 virtual status_t
IterateBezierTo(int32 bezierCount
, BPoint
* bezierPts
);
58 virtual status_t
IterateClose();
59 virtual status_t
IterateArcTo(float& rx
, float& ry
,
60 float& angle
, bool largeArc
, bool counterClockWise
, BPoint
& point
);
62 void Draw(BRect frame
, bool filled
);
66 stack
<uint32
> fOpStack
;
67 stack
<BPoint
> fPtStack
;
71 ShapePainter::ShapePainter(Canvas
* canvas
)
78 ShapePainter::~ShapePainter()
84 ShapePainter::Iterate(const BShape
* shape
)
86 // this class doesn't modify the shape data
87 return BShapeIterator::Iterate(const_cast<BShape
*>(shape
));
92 ShapePainter::IterateMoveTo(BPoint
* point
)
95 fOpStack
.push(OP_MOVETO
);
96 fPtStack
.push(*point
);
97 } catch (std::bad_alloc
) {
106 ShapePainter::IterateLineTo(int32 lineCount
, BPoint
* linePts
)
109 fOpStack
.push(OP_LINETO
| lineCount
);
110 for (int32 i
= 0; i
< lineCount
; i
++)
111 fPtStack
.push(linePts
[i
]);
112 } catch (std::bad_alloc
) {
121 ShapePainter::IterateBezierTo(int32 bezierCount
, BPoint
* bezierPts
)
125 fOpStack
.push(OP_BEZIERTO
| bezierCount
);
126 for (int32 i
= 0; i
< bezierCount
; i
++)
127 fPtStack
.push(bezierPts
[i
]);
128 } catch (std::bad_alloc
) {
137 ShapePainter::IterateArcTo(float& rx
, float& ry
,
138 float& angle
, bool largeArc
, bool counterClockWise
, BPoint
& point
)
142 if (counterClockWise
)
143 op
= OP_LARGE_ARC_TO_CCW
;
145 op
= OP_LARGE_ARC_TO_CW
;
147 if (counterClockWise
)
148 op
= OP_SMALL_ARC_TO_CCW
;
150 op
= OP_SMALL_ARC_TO_CW
;
154 fOpStack
.push(op
| 3);
155 fPtStack
.push(BPoint(rx
, ry
));
156 fPtStack
.push(BPoint(angle
, 0));
157 fPtStack
.push(point
);
158 } catch (std::bad_alloc
) {
167 ShapePainter::IterateClose()
170 fOpStack
.push(OP_CLOSE
);
171 } catch (std::bad_alloc
) {
180 ShapePainter::Draw(BRect frame
, bool filled
)
182 // We're going to draw the currently iterated shape.
183 // TODO: This can be more efficient by skipping the conversion.
184 int32 opCount
= fOpStack
.size();
185 int32 ptCount
= fPtStack
.size();
187 if (opCount
> 0 && ptCount
> 0) {
189 uint32
* opList
= new(std::nothrow
) uint32
[opCount
];
193 BPoint
* ptList
= new(std::nothrow
) BPoint
[ptCount
];
194 if (ptList
== NULL
) {
199 for (i
= opCount
- 1; i
>= 0; i
--) {
200 opList
[i
] = fOpStack
.top();
204 for (i
= ptCount
- 1; i
>= 0; i
--) {
205 ptList
[i
] = fPtStack
.top();
209 BPoint
offset(fCanvas
->CurrentState()->PenLocation());
210 fCanvas
->PenToScreenTransform().Apply(&offset
);
211 fCanvas
->GetDrawingEngine()->DrawShape(frame
, opCount
, opList
,
212 ptCount
, ptList
, filled
, offset
, fCanvas
->Scale());
220 // #pragma mark - drawing functions
224 get_polygon_frame(const BPoint
* points
, uint32 numPoints
, BRect
* _frame
)
226 ASSERT(numPoints
> 0);
228 float left
= points
->x
;
229 float top
= points
->y
;
236 while (numPoints
--) {
237 if (points
->x
< left
)
239 if (points
->x
> right
)
243 if (points
->y
> bottom
)
248 _frame
->Set(left
, top
, right
, bottom
);
253 move_pen_by(void* _canvas
, const BPoint
& delta
)
255 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
256 canvas
->CurrentState()->SetPenLocation(
257 canvas
->CurrentState()->PenLocation() + delta
);
262 stroke_line(void* _canvas
, const BPoint
& _start
, const BPoint
& _end
)
264 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
265 BPoint start
= _start
;
268 const SimpleTransform transform
= canvas
->PenToScreenTransform();
269 transform
.Apply(&start
);
270 transform
.Apply(&end
);
271 canvas
->GetDrawingEngine()->StrokeLine(start
, end
);
273 canvas
->CurrentState()->SetPenLocation(_end
);
274 // the DrawingEngine/Painter does not need to be updated, since this
275 // effects only the view->screen coord conversion, which is handled
281 draw_rect(void* _canvas
, const BRect
& _rect
, bool fill
)
283 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
286 canvas
->PenToScreenTransform().Apply(&rect
);
288 canvas
->GetDrawingEngine()->FillRect(rect
);
290 canvas
->GetDrawingEngine()->StrokeRect(rect
);
295 draw_round_rect(void* _canvas
, const BRect
& _rect
, const BPoint
& radii
,
298 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
301 canvas
->PenToScreenTransform().Apply(&rect
);
302 float scale
= canvas
->CurrentState()->CombinedScale();
303 canvas
->GetDrawingEngine()->DrawRoundRect(rect
, radii
.x
* scale
,
304 radii
.y
* scale
, fill
);
309 draw_bezier(void* _canvas
, size_t numPoints
, const BPoint viewPoints
[],
312 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
314 const size_t kSupportedPoints
= 4;
315 if (numPoints
!= kSupportedPoints
)
318 BPoint points
[kSupportedPoints
];
319 canvas
->PenToScreenTransform().Apply(points
, viewPoints
, kSupportedPoints
);
320 canvas
->GetDrawingEngine()->DrawBezier(points
, fill
);
325 draw_arc(void* _canvas
, const BPoint
& center
, const BPoint
& radii
,
326 float startTheta
, float arcTheta
, bool fill
)
328 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
330 BRect
rect(center
.x
- radii
.x
, center
.y
- radii
.y
,
331 center
.x
+ radii
.x
- 1, center
.y
+ radii
.y
- 1);
332 canvas
->PenToScreenTransform().Apply(&rect
);
333 canvas
->GetDrawingEngine()->DrawArc(rect
, startTheta
, arcTheta
, fill
);
338 draw_ellipse(void* _canvas
, const BRect
& _rect
, bool fill
)
340 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
343 canvas
->PenToScreenTransform().Apply(&rect
);
344 canvas
->GetDrawingEngine()->DrawEllipse(rect
, fill
);
349 draw_polygon(void* _canvas
, size_t numPoints
, const BPoint viewPoints
[],
350 bool isClosed
, bool fill
)
352 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
357 const size_t kMaxStackCount
= 200;
358 char stackData
[kMaxStackCount
* sizeof(BPoint
)];
359 BPoint
* points
= (BPoint
*)stackData
;
360 if (numPoints
> kMaxStackCount
) {
361 points
= (BPoint
*)malloc(numPoints
* sizeof(BPoint
));
366 canvas
->PenToScreenTransform().Apply(points
, viewPoints
, numPoints
);
369 get_polygon_frame(points
, numPoints
, &polyFrame
);
371 canvas
->GetDrawingEngine()->DrawPolygon(points
, numPoints
, polyFrame
,
372 fill
, isClosed
&& numPoints
> 2);
374 if (numPoints
> kMaxStackCount
)
380 draw_shape(void* _canvas
, const BShape
& shape
, bool fill
)
382 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
383 ShapePainter
drawShape(canvas
);
385 drawShape
.Iterate(&shape
);
386 drawShape
.Draw(shape
.Bounds(), fill
);
391 draw_string(void* _canvas
, const char* string
, size_t length
, float deltaSpace
,
394 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
396 // NOTE: the picture data was recorded with a "set pen location"
397 // command inserted before the "draw string" command, so we can
399 BPoint location
= canvas
->CurrentState()->PenLocation();
401 escapement_delta delta
= { deltaSpace
, deltaNonSpace
};
402 canvas
->PenToScreenTransform().Apply(&location
);
403 location
= canvas
->GetDrawingEngine()->DrawString(string
, length
,
406 canvas
->PenToScreenTransform().Apply(&location
);
407 canvas
->CurrentState()->SetPenLocation(location
);
408 // the DrawingEngine/Painter does not need to be updated, since this
409 // effects only the view->screen coord conversion, which is handled
415 draw_pixels(void* _canvas
, const BRect
& src
, const BRect
& _dest
, uint32 width
,
416 uint32 height
, size_t bytesPerRow
, color_space pixelFormat
, uint32 options
,
417 const void* data
, size_t length
)
419 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
421 UtilityBitmap
bitmap(BRect(0, 0, width
- 1, height
- 1),
422 (color_space
)pixelFormat
, 0, bytesPerRow
);
424 if (!bitmap
.IsValid())
427 memcpy(bitmap
.Bits(), data
, std::min(height
* bytesPerRow
, length
));
430 canvas
->PenToScreenTransform().Apply(&dest
);
431 canvas
->GetDrawingEngine()->DrawBitmap(&bitmap
, src
, dest
, options
);
436 draw_picture(void* _canvas
, const BPoint
& where
, int32 token
)
438 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
440 ServerPicture
* picture
= canvas
->GetPicture(token
);
441 if (picture
!= NULL
) {
443 canvas
->SetDrawingOrigin(where
);
446 picture
->Play(canvas
);
450 picture
->ReleaseReference();
456 set_clipping_rects(void* _canvas
, size_t numRects
, const BRect rects
[])
458 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
461 canvas
->SetUserClipping(NULL
);
463 // TODO: This might be too slow, we should copy the rects
464 // directly to BRegion's internal data
466 for (uint32 c
= 0; c
< numRects
; c
++)
467 region
.Include(rects
[c
]);
468 canvas
->SetUserClipping(®ion
);
470 canvas
->UpdateCurrentDrawingRegion();
475 clip_to_picture(void* _canvas
, int32 pictureToken
, const BPoint
& where
,
479 Canvas* const canvas = reinterpret_cast<Canvas*>(_canvas);
481 ServerPicture* picture = canvas->GetPicture(pictureToken);
485 AlphaMask* mask = new(std::nothrow) AlphaMask(
486 picture, clipToInverse, where, *canvas->CurrentState());
487 canvas->SetAlphaMask(mask);
488 canvas->UpdateCurrentDrawingRegion();
490 mask->ReleaseReference();
492 picture->ReleaseReference();
498 push_state(void* _canvas
)
500 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
506 pop_state(void* _canvas
)
508 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
512 canvas
->PenToScreenTransform().Apply(&p
);
513 canvas
->GetDrawingEngine()->SetDrawState(canvas
->CurrentState(),
514 (int32
)p
.x
, (int32
)p
.y
);
518 // TODO: Be smart and actually take advantage of these methods:
519 // only apply state changes when they are called
521 enter_state_change(void* _canvas
)
527 exit_state_change(void* _canvas
)
529 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
530 canvas
->ResyncDrawState();
535 enter_font_state(void* _canvas
)
541 exit_font_state(void* _canvas
)
543 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
544 canvas
->GetDrawingEngine()->SetFont(canvas
->CurrentState()->Font());
549 set_origin(void* _canvas
, const BPoint
& pt
)
551 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
552 canvas
->CurrentState()->SetOrigin(pt
);
557 set_pen_location(void* _canvas
, const BPoint
& pt
)
559 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
560 canvas
->CurrentState()->SetPenLocation(pt
);
561 // the DrawingEngine/Painter does not need to be updated, since this
562 // effects only the view->screen coord conversion, which is handled
568 set_drawing_mode(void* _canvas
, drawing_mode mode
)
570 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
571 if (canvas
->CurrentState()->SetDrawingMode(mode
))
572 canvas
->GetDrawingEngine()->SetDrawingMode(mode
);
577 set_line_mode(void* _canvas
, cap_mode capMode
, join_mode joinMode
,
580 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
581 DrawState
* state
= canvas
->CurrentState();
582 state
->SetLineCapMode(capMode
);
583 state
->SetLineJoinMode(joinMode
);
584 state
->SetMiterLimit(miterLimit
);
585 canvas
->GetDrawingEngine()->SetStrokeMode(capMode
, joinMode
, miterLimit
);
590 set_pen_size(void* _canvas
, float size
)
592 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
593 canvas
->CurrentState()->SetPenSize(size
);
594 canvas
->GetDrawingEngine()->SetPenSize(
595 canvas
->CurrentState()->PenSize());
596 // DrawState::PenSize() returns the scaled pen size, so we
597 // need to use that value to set the drawing engine pen size.
602 set_fore_color(void* _canvas
, const rgb_color
& color
)
604 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
605 canvas
->CurrentState()->SetHighColor(color
);
606 canvas
->GetDrawingEngine()->SetHighColor(color
);
611 set_back_color(void* _canvas
, const rgb_color
& color
)
613 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
614 canvas
->CurrentState()->SetLowColor(color
);
615 canvas
->GetDrawingEngine()->SetLowColor(color
);
620 set_stipple_pattern(void* _canvas
, const pattern
& pattern
)
622 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
623 canvas
->CurrentState()->SetPattern(Pattern(pattern
));
624 canvas
->GetDrawingEngine()->SetPattern(pattern
);
629 set_scale(void* _canvas
, float scale
)
631 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
632 canvas
->CurrentState()->SetScale(scale
);
633 canvas
->ResyncDrawState();
635 // Update the drawing engine draw state, since some stuff
636 // (for example the pen size) needs to be recalculated.
641 set_font_family(void* _canvas
, const char* _family
, size_t length
)
643 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
644 BString
family(_family
, length
);
646 FontStyle
* fontStyle
= gFontManager
->GetStyleByIndex(family
, 0);
648 font
.SetStyle(fontStyle
);
649 canvas
->CurrentState()->SetFont(font
, B_FONT_FAMILY_AND_STYLE
);
654 set_font_style(void* _canvas
, const char* _style
, size_t length
)
656 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
657 BString
style(_style
, length
);
659 ServerFont
font(canvas
->CurrentState()->Font());
661 FontStyle
* fontStyle
= gFontManager
->GetStyle(font
.Family(), style
);
663 font
.SetStyle(fontStyle
);
664 canvas
->CurrentState()->SetFont(font
, B_FONT_FAMILY_AND_STYLE
);
669 set_font_spacing(void* _canvas
, uint8 spacing
)
671 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
673 font
.SetSpacing(spacing
);
674 canvas
->CurrentState()->SetFont(font
, B_FONT_SPACING
);
679 set_font_size(void* _canvas
, float size
)
681 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
684 canvas
->CurrentState()->SetFont(font
, B_FONT_SIZE
);
689 set_font_rotation(void* _canvas
, float rotation
)
691 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
693 font
.SetRotation(rotation
);
694 canvas
->CurrentState()->SetFont(font
, B_FONT_ROTATION
);
699 set_font_encoding(void* _canvas
, uint8 encoding
)
701 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
703 font
.SetEncoding(encoding
);
704 canvas
->CurrentState()->SetFont(font
, B_FONT_ENCODING
);
709 set_font_flags(void* _canvas
, uint32 flags
)
711 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
713 font
.SetFlags(flags
);
714 canvas
->CurrentState()->SetFont(font
, B_FONT_FLAGS
);
719 set_font_shear(void* _canvas
, float shear
)
721 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
723 font
.SetShear(shear
);
724 canvas
->CurrentState()->SetFont(font
, B_FONT_SHEAR
);
729 set_font_face(void* _canvas
, uint16 face
)
731 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
734 canvas
->CurrentState()->SetFont(font
, B_FONT_FACE
);
739 set_blending_mode(void* _canvas
, source_alpha alphaSrcMode
,
740 alpha_function alphaFncMode
)
742 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
743 canvas
->CurrentState()->SetBlendingMode(alphaSrcMode
, alphaFncMode
);
748 set_transform(void* _canvas
, const BAffineTransform
& transform
)
750 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
751 canvas
->CurrentState()->SetTransform(transform
);
752 canvas
->GetDrawingEngine()->SetTransform(transform
);
757 translate_by(void* _canvas
, double x
, double y
)
759 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
760 BAffineTransform transform
= canvas
->CurrentState()->Transform();
761 transform
.PreTranslateBy(x
, y
);
762 canvas
->CurrentState()->SetTransform(transform
);
763 canvas
->GetDrawingEngine()->SetTransform(transform
);
768 scale_by(void* _canvas
, double x
, double y
)
770 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
771 BAffineTransform transform
= canvas
->CurrentState()->Transform();
772 transform
.PreScaleBy(x
, y
);
773 canvas
->CurrentState()->SetTransform(transform
);
774 canvas
->GetDrawingEngine()->SetTransform(transform
);
779 rotate_by(void* _canvas
, double angleRadians
)
781 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
782 BAffineTransform transform
= canvas
->CurrentState()->Transform();
783 transform
.PreRotateBy(angleRadians
);
784 canvas
->CurrentState()->SetTransform(transform
);
785 canvas
->GetDrawingEngine()->SetTransform(transform
);
790 blend_layer(void* _canvas
, Layer
* layer
)
792 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
793 canvas
->BlendLayer(layer
);
798 clip_to_rect(void* _canvas
, const BRect
& rect
, bool inverse
)
800 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
801 bool needDrawStateUpdate
= canvas
->ClipToRect(rect
, inverse
);
802 if (needDrawStateUpdate
) {
803 canvas
->CurrentState()->GetAlphaMask()->SetCanvasGeometry(BPoint(0, 0),
805 canvas
->ResyncDrawState();
807 canvas
->UpdateCurrentDrawingRegion();
812 clip_to_shape(void* _canvas
, int32 opCount
, const uint32 opList
[],
813 int32 ptCount
, const BPoint ptList
[], bool inverse
)
815 Canvas
* const canvas
= reinterpret_cast<Canvas
*>(_canvas
);
816 shape_data shapeData
;
818 // TODO: avoid copies
819 shapeData
.opList
= (uint32
*)malloc(opCount
* sizeof(uint32
));
820 memcpy(shapeData
.opList
, opList
, opCount
* sizeof(uint32
));
821 shapeData
.ptList
= (BPoint
*)malloc(ptCount
* sizeof(BPoint
));
822 memcpy(shapeData
.ptList
, ptList
, ptCount
* sizeof(BPoint
));
824 shapeData
.opCount
= opCount
;
825 shapeData
.opSize
= opCount
* sizeof(uint32
);
826 shapeData
.ptCount
= ptCount
;
827 shapeData
.ptSize
= ptCount
* sizeof(BPoint
);
829 canvas
->ClipToShape(&shapeData
, inverse
);
830 canvas
->CurrentState()->GetAlphaMask()->SetCanvasGeometry(BPoint(0, 0),
832 canvas
->ResyncDrawState();
834 free(shapeData
.opList
);
835 free(shapeData
.ptList
);
839 static const BPrivate::picture_player_callbacks kPicturePlayerCallbacks
= {
889 // #pragma mark - ServerPicture
892 ServerPicture::ServerPicture()
899 fToken
= gTokenSpace
.NewToken(kPictureToken
, this);
900 fData
= new(std::nothrow
) BMallocIO();
902 PictureDataWriter::SetTo(fData
);
906 ServerPicture::ServerPicture(const ServerPicture
& picture
)
914 fToken
= gTokenSpace
.NewToken(kPictureToken
, this);
916 BMallocIO
* mallocIO
= new(std::nothrow
) BMallocIO();
917 if (mallocIO
== NULL
)
922 const off_t size
= picture
.DataLength();
923 if (mallocIO
->SetSize(size
) < B_OK
)
926 picture
.fData
->ReadAt(0, const_cast<void*>(mallocIO
->Buffer()),
929 PictureDataWriter::SetTo(fData
);
933 ServerPicture::ServerPicture(const char* fileName
, int32 offset
)
941 fToken
= gTokenSpace
.NewToken(kPictureToken
, this);
943 fFile
= new(std::nothrow
) BFile(fileName
, B_READ_WRITE
);
947 BPrivate::Storage::OffsetFile
* offsetFile
948 = new(std::nothrow
) BPrivate::Storage::OffsetFile(fFile
, offset
);
949 if (offsetFile
== NULL
|| offsetFile
->InitCheck() != B_OK
) {
956 PictureDataWriter::SetTo(fData
);
960 ServerPicture::~ServerPicture()
962 ASSERT(fOwner
== NULL
);
966 gTokenSpace
.RemoveToken(fToken
);
968 if (fPictures
!= NULL
) {
969 for (int32 i
= fPictures
->CountItems(); i
-- > 0;) {
970 ServerPicture
* picture
= fPictures
->ItemAt(i
);
971 picture
->SetOwner(NULL
);
972 picture
->ReleaseReference();
978 if (fPushed
!= NULL
) {
979 fPushed
->SetOwner(NULL
);
980 fPushed
->ReleaseReference();
986 ServerPicture::SetOwner(ServerApp
* owner
)
991 // Acquire an extra reference, since calling RemovePicture()
992 // May remove the last reference and then we will self-destruct right then.
993 // Setting fOwner to NULL would access free'd memory. If owner is another
994 // ServerApp, it's expected to already have a reference of course.
995 BReference
<ServerPicture
> _(this);
998 fOwner
->RemovePicture(this);
1004 if (!owner
->AddPicture(this))
1013 ServerPicture::EnterStateChange()
1015 BeginOp(B_PIC_ENTER_STATE_CHANGE
);
1020 ServerPicture::ExitStateChange()
1027 ServerPicture::SyncState(View
* view
)
1029 // TODO: Finish this
1032 WriteSetOrigin(view
->CurrentState()->Origin());
1033 WriteSetPenLocation(view
->CurrentState()->PenLocation());
1034 WriteSetPenSize(view
->CurrentState()->UnscaledPenSize());
1035 WriteSetScale(view
->CurrentState()->Scale());
1036 WriteSetLineMode(view
->CurrentState()->LineCapMode(),
1037 view
->CurrentState()->LineJoinMode(),
1038 view
->CurrentState()->MiterLimit());
1039 //WriteSetPattern(*view->CurrentState()->GetPattern().GetInt8());
1040 WriteSetDrawingMode(view
->CurrentState()->GetDrawingMode());
1042 WriteSetHighColor(view
->CurrentState()->HighColor());
1043 WriteSetLowColor(view
->CurrentState()->LowColor());
1050 ServerPicture::SetFontFromLink(BPrivate::LinkReceiver
& link
)
1052 BeginOp(B_PIC_ENTER_FONT_STATE
);
1055 link
.Read
<uint16
>(&mask
);
1057 if (mask
& B_FONT_FAMILY_AND_STYLE
) {
1059 link
.Read
<uint32
>(&fontID
);
1061 font
.SetFamilyAndStyle(fontID
);
1062 WriteSetFontFamily(font
.Family());
1063 WriteSetFontStyle(font
.Style());
1066 if (mask
& B_FONT_SIZE
) {
1068 link
.Read
<float>(&size
);
1069 WriteSetFontSize(size
);
1072 if (mask
& B_FONT_SHEAR
) {
1074 link
.Read
<float>(&shear
);
1075 WriteSetFontShear(shear
);
1078 if (mask
& B_FONT_ROTATION
) {
1080 link
.Read
<float>(&rotation
);
1081 WriteSetFontRotation(rotation
);
1084 if (mask
& B_FONT_FALSE_BOLD_WIDTH
) {
1085 float falseBoldWidth
;
1086 link
.Read
<float>(&falseBoldWidth
);
1087 //SetFalseBoldWidth(falseBoldWidth);
1090 if (mask
& B_FONT_SPACING
) {
1092 link
.Read
<uint8
>(&spacing
);
1093 WriteSetFontSpacing(spacing
);
1096 if (mask
& B_FONT_ENCODING
) {
1098 link
.Read
<uint8
>((uint8
*)&encoding
);
1099 WriteSetFontEncoding(encoding
);
1102 if (mask
& B_FONT_FACE
) {
1104 link
.Read
<uint16
>(&face
);
1105 WriteSetFontFace(face
);
1108 if (mask
& B_FONT_FLAGS
) {
1110 link
.Read
<uint32
>(&flags
);
1111 WriteSetFontFlags(flags
);
1119 ServerPicture::Play(Canvas
* target
)
1121 // TODO: for now: then change PicturePlayer
1122 // to accept a BPositionIO object
1123 BMallocIO
* mallocIO
= dynamic_cast<BMallocIO
*>(fData
);
1124 if (mallocIO
== NULL
)
1127 BPrivate::PicturePlayer
player(mallocIO
->Buffer(),
1128 mallocIO
->BufferLength(), PictureList::Private(fPictures
).AsBList());
1129 player
.Play(kPicturePlayerCallbacks
, sizeof(kPicturePlayerCallbacks
),
1134 /*! Acquires a reference to the pushed picture.
1137 ServerPicture::PushPicture(ServerPicture
* picture
)
1139 if (fPushed
!= NULL
)
1140 debugger("already pushed a picture");
1143 fPushed
->AcquireReference();
1147 /*! Returns a reference with the popped picture.
1150 ServerPicture::PopPicture()
1152 ServerPicture
* old
= fPushed
;
1159 ServerPicture::AppendPicture(ServerPicture
* picture
)
1161 // A pushed picture is the same as an appended one
1162 PushPicture(picture
);
1167 ServerPicture::NestPicture(ServerPicture
* picture
)
1169 if (fPictures
== NULL
)
1170 fPictures
= new(std::nothrow
) PictureList
;
1172 if (fPictures
== NULL
|| !fPictures
->AddItem(picture
))
1175 picture
->AcquireReference();
1181 ServerPicture::DataLength() const
1186 fData
->GetSize(&size
);
1192 ServerPicture::ImportData(BPrivate::LinkReceiver
& link
)
1195 link
.Read
<int32
>(&size
);
1197 off_t oldPosition
= fData
->Position();
1198 fData
->Seek(0, SEEK_SET
);
1200 status_t status
= B_NO_MEMORY
;
1201 char* buffer
= new(std::nothrow
) char[size
];
1204 ssize_t read
= link
.Read(buffer
, size
);
1205 if (read
< B_OK
|| fData
->Write(buffer
, size
) < B_OK
)
1210 fData
->Seek(oldPosition
, SEEK_SET
);
1216 ServerPicture::ExportData(BPrivate::PortLink
& link
)
1218 link
.StartMessage(B_OK
);
1220 off_t oldPosition
= fData
->Position();
1221 fData
->Seek(0, SEEK_SET
);
1223 int32 subPicturesCount
= 0;
1224 if (fPictures
!= NULL
)
1225 subPicturesCount
= fPictures
->CountItems();
1226 link
.Attach
<int32
>(subPicturesCount
);
1227 if (subPicturesCount
> 0) {
1228 for (int32 i
= 0; i
< subPicturesCount
; i
++) {
1229 ServerPicture
* subPicture
= fPictures
->ItemAt(i
);
1230 link
.Attach
<int32
>(subPicture
->Token());
1235 fData
->GetSize(&size
);
1236 link
.Attach
<int32
>((int32
)size
);
1238 status_t status
= B_NO_MEMORY
;
1239 char* buffer
= new(std::nothrow
) char[size
];
1242 ssize_t read
= fData
->Read(buffer
, size
);
1243 if (read
< B_OK
|| link
.Attach(buffer
, read
) < B_OK
)
1248 if (status
!= B_OK
) {
1249 link
.CancelMessage();
1250 link
.StartMessage(B_ERROR
);
1253 fData
->Seek(oldPosition
, SEEK_SET
);