diff --git a/src/servers/app/DrawingContext.cpp b/src/servers/app/DrawingContext.cpp new file mode 100644 index 0000000000..d7ec4381a4 --- /dev/null +++ b/src/servers/app/DrawingContext.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2001-2014, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * DarkWyrm + * Adi Oanca + * Axel Dörfler, axeld@pinc-software.de + * Stephan Aßmus + * Marcus Overhagen + * Adrien Destugues + +#include +#include +#include +#include +#include +#include + +#include "DrawState.h" + + +DrawingContext::DrawingContext() + : + fDrawState(new (nothrow) DrawState) +{ +} + + + +void +DrawingContext::PushState() +{ + DrawState* newState = fDrawState->PushState(); + if (newState) { + fDrawState = newState; + } +} + + +void +DrawingContext::PopState() +{ + if (fDrawState->PreviousState() == NULL) { + return; + } + + bool rebuildClipping = fDrawState->HasAdditionalClipping(); + + fDrawState = fDrawState->PopState(); + + // rebuild clipping + // (the clipping from the popped state is not effective anymore) + if (rebuildClipping) + RebuildClipping(false); +} + + +void +DrawingContext::SetDrawingOrigin(BPoint origin) +{ + fDrawState->SetOrigin(origin); + + // rebuild clipping + if (fDrawState->HasClipping()) + RebuildClipping(false); +} + + +BPoint +DrawingContext::DrawingOrigin() const +{ + BPoint origin(fDrawState->Origin()); + float scale = Scale(); + + origin.x *= scale; + origin.y *= scale; + + return origin; +} + + +void +DrawingContext::SetScale(float scale) +{ + fDrawState->SetScale(scale); + + // rebuild clipping + if (fDrawState->HasClipping()) + RebuildClipping(false); +} + + +float +DrawingContext::Scale() const +{ + return CurrentState()->Scale(); +} + + +void +DrawingContext::SetUserClipping(const BRegion* region) +{ + fDrawState->SetClippingRegion(region); + + // rebuild clipping (for just this view) + RebuildClipping(false); +} + + +//! converts a point from local *drawing* to screen coordinate system +void +DrawingContext::ConvertToScreenForDrawing(BPoint* point) const +{ + fDrawState->Transform(point); + // NOTE: from here on, don't use the + // "*ForDrawing()" versions of the parent! + ConvertToScreen(point); +} + + +//! converts a rect from local *drawing* to screen coordinate system +void +DrawingContext::ConvertToScreenForDrawing(BRect* rect) const +{ + fDrawState->Transform(rect); + // NOTE: from here on, don't use the + // "*ForDrawing()" versions of the parent! + ConvertToScreen(rect); +} + + +//! converts a region from local *drawing* to screen coordinate system +void +DrawingContext::ConvertToScreenForDrawing(BRegion* region) const +{ + fDrawState->Transform(region); + // NOTE: from here on, don't use the + // "*ForDrawing()" versions of the parent! + ConvertToScreen(region); +} + + +//! converts a gradient from local *drawing* to screen coordinate system +void +DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const +{ + switch(gradient->GetType()) { + case BGradient::TYPE_LINEAR: { + BGradientLinear* linear = (BGradientLinear*) gradient; + BPoint start = linear->Start(); + BPoint end = linear->End(); + fDrawState->Transform(&start); + ConvertToScreen(&start); + fDrawState->Transform(&end); + ConvertToScreen(&end); + linear->SetStart(start); + linear->SetEnd(end); + linear->SortColorStopsByOffset(); + break; + } + case BGradient::TYPE_RADIAL: { + BGradientRadial* radial = (BGradientRadial*) gradient; + BPoint center = radial->Center(); + fDrawState->Transform(¢er); + ConvertToScreen(¢er); + radial->SetCenter(center); + radial->SortColorStopsByOffset(); + break; + } + case BGradient::TYPE_RADIAL_FOCUS: { + BGradientRadialFocus* radialFocus = (BGradientRadialFocus*) gradient; + BPoint center = radialFocus->Center(); + BPoint focal = radialFocus->Focal(); + fDrawState->Transform(¢er); + ConvertToScreen(¢er); + fDrawState->Transform(&focal); + ConvertToScreen(&focal); + radialFocus->SetCenter(center); + radialFocus->SetFocal(focal); + radialFocus->SortColorStopsByOffset(); + break; + } + case BGradient::TYPE_DIAMOND: { + BGradientDiamond* diamond = (BGradientDiamond*) gradient; + BPoint center = diamond->Center(); + fDrawState->Transform(¢er); + ConvertToScreen(¢er); + diamond->SetCenter(center); + diamond->SortColorStopsByOffset(); + break; + } + case BGradient::TYPE_CONIC: { + BGradientConic* conic = (BGradientConic*) gradient; + BPoint center = conic->Center(); + fDrawState->Transform(¢er); + ConvertToScreen(¢er); + conic->SetCenter(center); + conic->SortColorStopsByOffset(); + break; + } + case BGradient::TYPE_NONE: { + break; + } + } +} + + +//! converts points from local *drawing* to screen coordinate system +void +DrawingContext::ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const +{ + // TODO: optimize this, it should be smarter + while (num--) { + *dst = *src; + fDrawState->Transform(dst); + // NOTE: from here on, don't use the + // "*ForDrawing()" versions of the parent! + ConvertToScreen(dst); + src++; + dst++; + } +} + + +//! converts rects from local *drawing* to screen coordinate system +void +DrawingContext::ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const +{ + // TODO: optimize this, it should be smarter + while (num--) { + *dst = *src; + fDrawState->Transform(dst); + // NOTE: from here on, don't use the + // "*ForDrawing()" versions of the parent! + ConvertToScreen(dst); + src++; + dst++; + } +} + + +//! converts regions from local *drawing* to screen coordinate system +void +DrawingContext::ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const +{ + // TODO: optimize this, it should be smarter + while (num--) { + *dst = *src; + fDrawState->Transform(dst); + // NOTE: from here on, don't use the + // "*ForDrawing()" versions of the parent! + ConvertToScreen(dst); + src++; + dst++; + } +} + + +//! converts a point from screen to local coordinate system +void +DrawingContext::ConvertFromScreenForDrawing(BPoint* point) const +{ + ConvertFromScreen(point); + fDrawState->InverseTransform(point); +} + + diff --git a/src/servers/app/DrawingContext.h b/src/servers/app/DrawingContext.h new file mode 100644 index 0000000000..fb8b8f9f94 --- /dev/null +++ b/src/servers/app/DrawingContext.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2001-2014, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Authors: + * DarkWyrm + * Adi Oanca + * Axel Dörfler, axeld@pinc-software.de + * Stephan Aßmus + * Marcus Overhagen + * Adrien Destugues + */ +#ifndef DRAWINGCONTEXT_H +#define DRAWINGCONTEXT_H + + +#include + + +class BGradient; +class BRegion; +class DrawingEngine; +class DrawState; +class IntPoint; +class IntRect; +class ServerPicture; + + +class DrawingContext { + public: + DrawingContext(); + + virtual void PushState(); + virtual void PopState(); + DrawState* CurrentState() const { return fDrawState; } + + void SetDrawingOrigin(BPoint origin); + BPoint DrawingOrigin() const; + + void SetScale(float scale); + float Scale() const; + + void SetUserClipping(const BRegion* region); + // region is expected in view coordinates + + void ConvertToScreenForDrawing(BPoint* point) const; + void ConvertToScreenForDrawing(BRect* rect) const; + void ConvertToScreenForDrawing(BRegion* region) const; + void ConvertToScreenForDrawing(BGradient* gradient) const; + + void ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const; + void ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const; + void ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const; + + void ConvertFromScreenForDrawing(BPoint* point) const; + // used when updating the pen position + + virtual void ConvertToScreen(BPoint* point) const = 0; + virtual void ConvertToScreen(IntPoint* point) const = 0; + virtual void ConvertToScreen(BRect* rect) const = 0; + virtual void ConvertToScreen(IntRect* rect) const = 0; + virtual void ConvertToScreen(BRegion* region) const = 0; + + virtual void ConvertFromScreen(BPoint* point) const = 0; + + virtual DrawingEngine* GetDrawingEngine() const = 0; + virtual ServerPicture* GetPicture(int32 token) const = 0; + virtual void RebuildClipping(bool deep) = 0; + virtual void ResyncDrawState() {}; + virtual void UpdateCurrentDrawingRegion() {}; + + protected: + DrawState* fDrawState; +}; + + +#endif diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 25792303d9..3e66e52c58 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -32,9 +32,9 @@ local font_src = UseBuildFeatureHeaders freetype ; Includes [ FGristFiles AppServer.cpp BitmapManager.cpp - ClientMemoryAllocator.cpp Desktop.cpp DesktopSettings.cpp DrawState.cpp - ServerApp.cpp ServerBitmap.cpp ServerFont.cpp ServerPicture.cpp - ServerWindow.cpp View.cpp Window.cpp WorkspacesView.cpp + ClientMemoryAllocator.cpp Desktop.cpp DesktopSettings.cpp + DrawState.cpp ServerApp.cpp ServerBitmap.cpp ServerFont.cpp + ServerPicture.cpp ServerWindow.cpp View.cpp Window.cpp WorkspacesView.cpp $(decorator_src) $(font_src) ] : [ BuildFeatureAttribute freetype : headers ] ; @@ -58,6 +58,7 @@ Server app_server : DesktopListener.cpp DesktopSettings.cpp DirectWindowInfo.cpp + DrawingContext.cpp DrawState.cpp EventDispatcher.cpp EventStream.cpp diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 3e094cd899..d0df802036 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -44,7 +44,7 @@ using std::stack; class ShapePainter : public BShapeIterator { public: - ShapePainter(View* view); + ShapePainter(DrawingContext* view); virtual ~ShapePainter(); status_t Iterate(const BShape* shape); @@ -59,13 +59,13 @@ public: void Draw(BRect frame, bool filled); private: - View* fView; + DrawingContext* fView; stack fOpStack; stack fPtStack; }; -ShapePainter::ShapePainter(View* view) +ShapePainter::ShapePainter(DrawingContext* view) : fView(view) { @@ -205,8 +205,8 @@ ShapePainter::Draw(BRect frame, bool filled) BPoint offset(fView->CurrentState()->PenLocation()); fView->ConvertToScreenForDrawing(&offset); - fView->Window()->GetDrawingEngine()->DrawShape(frame, opCount, - opList, ptCount, ptList, filled, offset, fView->Scale()); + fView->GetDrawingEngine()->DrawShape(frame, opCount, opList, ptCount, + ptList, filled, offset, fView->Scale()); delete[] opList; delete[] ptList; @@ -253,7 +253,7 @@ nop() static void -move_pen_by(View* view, BPoint delta) +move_pen_by(DrawingContext* view, BPoint delta) { view->CurrentState()->SetPenLocation( view->CurrentState()->PenLocation() + delta); @@ -261,13 +261,13 @@ move_pen_by(View* view, BPoint delta) static void -stroke_line(View* view, BPoint start, BPoint end) +stroke_line(DrawingContext* view, BPoint start, BPoint end) { BPoint penPos = end; view->ConvertToScreenForDrawing(&start); view->ConvertToScreenForDrawing(&end); - view->Window()->GetDrawingEngine()->StrokeLine(start, end); + view->GetDrawingEngine()->StrokeLine(start, end); view->CurrentState()->SetPenLocation(penPos); // the DrawingEngine/Painter does not need to be updated, since this @@ -277,105 +277,103 @@ stroke_line(View* view, BPoint start, BPoint end) static void -stroke_rect(View* view, BRect rect) +stroke_rect(DrawingContext* view, BRect rect) { view->ConvertToScreenForDrawing(&rect); - view->Window()->GetDrawingEngine()->StrokeRect(rect); + view->GetDrawingEngine()->StrokeRect(rect); } static void -fill_rect(View* view, BRect rect) +fill_rect(DrawingContext* view, BRect rect) { view->ConvertToScreenForDrawing(&rect); - view->Window()->GetDrawingEngine()->FillRect(rect); + view->GetDrawingEngine()->FillRect(rect); } static void -stroke_round_rect(View* view, BRect rect, BPoint radii) +stroke_round_rect(DrawingContext* view, BRect rect, BPoint radii) { view->ConvertToScreenForDrawing(&rect); - view->Window()->GetDrawingEngine()->DrawRoundRect(rect, radii.x, + view->GetDrawingEngine()->DrawRoundRect(rect, radii.x, radii.y, false); } static void -fill_round_rect(View* view, BRect rect, BPoint radii) +fill_round_rect(DrawingContext* view, BRect rect, BPoint radii) { view->ConvertToScreenForDrawing(&rect); - view->Window()->GetDrawingEngine()->DrawRoundRect(rect, radii.x, - radii.y, true); + view->GetDrawingEngine()->DrawRoundRect(rect, radii.x, radii.y, true); } static void -stroke_bezier(View* view, const BPoint* viewPoints) +stroke_bezier(DrawingContext* view, const BPoint* viewPoints) { BPoint points[4]; view->ConvertToScreenForDrawing(points, viewPoints, 4); - view->Window()->GetDrawingEngine()->DrawBezier(points, false); + view->GetDrawingEngine()->DrawBezier(points, false); } static void -fill_bezier(View* view, const BPoint* viewPoints) +fill_bezier(DrawingContext* view, const BPoint* viewPoints) { BPoint points[4]; view->ConvertToScreenForDrawing(points, viewPoints, 4); - view->Window()->GetDrawingEngine()->DrawBezier(points, true); + view->GetDrawingEngine()->DrawBezier(points, true); } static void -stroke_arc(View* view, BPoint center, BPoint radii, float startTheta, +stroke_arc(DrawingContext* view, BPoint center, BPoint radii, float startTheta, float arcTheta) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); view->ConvertToScreenForDrawing(&rect); - view->Window()->GetDrawingEngine()->DrawArc(rect, startTheta, - arcTheta, false); + view->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, false); } static void -fill_arc(View* view, BPoint center, BPoint radii, float startTheta, +fill_arc(DrawingContext* view, BPoint center, BPoint radii, float startTheta, float arcTheta) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); view->ConvertToScreenForDrawing(&rect); - view->Window()->GetDrawingEngine()->DrawArc(rect, startTheta, + view->GetDrawingEngine()->DrawArc(rect, startTheta, arcTheta, true); } static void -stroke_ellipse(View* view, BPoint center, BPoint radii) +stroke_ellipse(DrawingContext* view, BPoint center, BPoint radii) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); view->ConvertToScreenForDrawing(&rect); - view->Window()->GetDrawingEngine()->DrawEllipse(rect, false); + view->GetDrawingEngine()->DrawEllipse(rect, false); } static void -fill_ellipse(View* view, BPoint center, BPoint radii) +fill_ellipse(DrawingContext* view, BPoint center, BPoint radii) { BRect rect(center.x - radii.x, center.y - radii.y, center.x + radii.x - 1, center.y + radii.y - 1); view->ConvertToScreenForDrawing(&rect); - view->Window()->GetDrawingEngine()->DrawEllipse(rect, true); + view->GetDrawingEngine()->DrawEllipse(rect, true); } static void -stroke_polygon(View* view, int32 numPoints, const BPoint* viewPoints, +stroke_polygon(DrawingContext* view, int32 numPoints, const BPoint* viewPoints, bool isClosed) { if (numPoints <= 0) @@ -392,8 +390,8 @@ stroke_polygon(View* view, int32 numPoints, const BPoint* viewPoints, BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); - view->Window()->GetDrawingEngine()->DrawPolygon(points, - numPoints, polyFrame, false, isClosed && numPoints > 2); + view->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + false, isClosed && numPoints > 2); } else { // avoid constructor/destructor calls by // using malloc instead of new [] @@ -406,15 +404,15 @@ stroke_polygon(View* view, int32 numPoints, const BPoint* viewPoints, BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); - view->Window()->GetDrawingEngine()->DrawPolygon(points, - numPoints, polyFrame, false, isClosed && numPoints > 2); + view->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + false, isClosed && numPoints > 2); free(points); } } static void -fill_polygon(View* view, int32 numPoints, const BPoint* viewPoints) +fill_polygon(DrawingContext* view, int32 numPoints, const BPoint* viewPoints) { if (numPoints <= 0) return; @@ -430,8 +428,8 @@ fill_polygon(View* view, int32 numPoints, const BPoint* viewPoints) BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); - view->Window()->GetDrawingEngine()->DrawPolygon(points, - numPoints, polyFrame, true, true); + view->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + true, true); } else { // avoid constructor/destructor calls by // using malloc instead of new [] @@ -444,15 +442,15 @@ fill_polygon(View* view, int32 numPoints, const BPoint* viewPoints) BRect polyFrame; get_polygon_frame(points, numPoints, &polyFrame); - view->Window()->GetDrawingEngine()->DrawPolygon(points, - numPoints, polyFrame, true, true); + view->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + true, true); free(points); } } static void -stroke_shape(View* view, const BShape* shape) +stroke_shape(DrawingContext* view, const BShape* shape) { ShapePainter drawShape(view); @@ -462,7 +460,7 @@ stroke_shape(View* view, const BShape* shape) static void -fill_shape(View* view, const BShape* shape) +fill_shape(DrawingContext* view, const BShape* shape) { ShapePainter drawShape(view); @@ -472,7 +470,7 @@ fill_shape(View* view, const BShape* shape) static void -draw_string(View* view, const char* string, float deltaSpace, +draw_string(DrawingContext* view, const char* string, float deltaSpace, float deltaNonSpace) { // NOTE: the picture data was recorded with a "set pen location" @@ -482,8 +480,8 @@ draw_string(View* view, const char* string, float deltaSpace, escapement_delta delta = {deltaSpace, deltaNonSpace }; view->ConvertToScreenForDrawing(&location); - view->Window()->GetDrawingEngine()->DrawString(string, - strlen(string), location, &delta); + view->GetDrawingEngine()->DrawString(string, strlen(string), location, + &delta); view->ConvertFromScreenForDrawing(&location); view->CurrentState()->SetPenLocation(location); @@ -494,7 +492,7 @@ draw_string(View* view, const char* string, float deltaSpace, static void -draw_pixels(View* view, BRect src, BRect dest, int32 width, +draw_pixels(DrawingContext* view, BRect src, BRect dest, int32 width, int32 height, int32 bytesPerRow, int32 pixelFormat, int32 options, const void* data) { @@ -507,15 +505,14 @@ draw_pixels(View* view, BRect src, BRect dest, int32 width, memcpy(bitmap.Bits(), data, height * bytesPerRow); view->ConvertToScreenForDrawing(&dest); - view->Window()->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, options); + view->GetDrawingEngine()->DrawBitmap(&bitmap, src, dest, options); } static void -draw_picture(View* view, BPoint where, int32 token) +draw_picture(DrawingContext* view, BPoint where, int32 token) { - ServerPicture* picture - = view->Window()->ServerWindow()->App()->GetPicture(token); + ServerPicture* picture = view->GetPicture(token); if (picture != NULL) { view->PushState(); view->SetDrawingOrigin(where); @@ -531,7 +528,7 @@ draw_picture(View* view, BPoint where, int32 token) static void -set_clipping_rects(View* view, const BRect* rects, uint32 numRects) +set_clipping_rects(DrawingContext* view, const BRect* rects, uint32 numRects) { // TODO: This might be too slow, we should copy the rects // directly to BRegion's internal data @@ -539,12 +536,13 @@ set_clipping_rects(View* view, const BRect* rects, uint32 numRects) for (uint32 c = 0; c < numRects; c++) region.Include(rects[c]); view->SetUserClipping(®ion); - view->Window()->ServerWindow()->UpdateCurrentDrawingRegion(); + view->UpdateCurrentDrawingRegion(); } static void -clip_to_picture(View* view, BPicture* picture, BPoint pt, bool clipToInverse) +clip_to_picture(DrawingContext* view, BPicture* picture, BPoint pt, + bool clipToInverse) { printf("ClipToPicture(picture, BPoint(%.2f, %.2f), %s)\n", pt.x, pt.y, clipToInverse ? "inverse" : ""); @@ -552,62 +550,61 @@ clip_to_picture(View* view, BPicture* picture, BPoint pt, bool clipToInverse) static void -push_state(View* view) +push_state(DrawingContext* view) { view->PushState(); } static void -pop_state(View* view) +pop_state(DrawingContext* view) { view->PopState(); BPoint p(0, 0); view->ConvertToScreenForDrawing(&p); - view->Window()->GetDrawingEngine()->SetDrawState( - view->CurrentState(), (int32)p.x, (int32)p.y); + view->GetDrawingEngine()->SetDrawState(view->CurrentState(), (int32)p.x, + (int32)p.y); } // TODO: Be smart and actually take advantage of these methods: // only apply state changes when they are called static void -enter_state_change(View* view) +enter_state_change(DrawingContext* view) { } static void -exit_state_change(View* view) +exit_state_change(DrawingContext* view) { - view->Window()->ServerWindow()->ResyncDrawState(); + view->ResyncDrawState(); } static void -enter_font_state(View* view) +enter_font_state(DrawingContext* view) { } static void -exit_font_state(View* view) +exit_font_state(DrawingContext* view) { - view->Window()->GetDrawingEngine()->SetFont( - view->CurrentState()->Font()); + view->GetDrawingEngine()->SetFont(view->CurrentState()->Font()); } static void -set_origin(View* view, BPoint pt) +set_origin(DrawingContext* view, BPoint pt) { view->CurrentState()->SetOrigin(pt); } static void -set_pen_location(View* view, BPoint pt) +set_pen_location(DrawingContext* view, BPoint pt) { view->CurrentState()->SetPenLocation(pt); // the DrawingEngine/Painter does not need to be updated, since this @@ -617,66 +614,64 @@ set_pen_location(View* view, BPoint pt) static void -set_drawing_mode(View* view, drawing_mode mode) +set_drawing_mode(DrawingContext* view, drawing_mode mode) { view->CurrentState()->SetDrawingMode(mode); - view->Window()->GetDrawingEngine()->SetDrawingMode(mode); + view->GetDrawingEngine()->SetDrawingMode(mode); } static void -set_line_mode(View* view, cap_mode capMode, join_mode joinMode, +set_line_mode(DrawingContext* view, cap_mode capMode, join_mode joinMode, float miterLimit) { DrawState* state = view->CurrentState(); state->SetLineCapMode(capMode); state->SetLineJoinMode(joinMode); state->SetMiterLimit(miterLimit); - view->Window()->GetDrawingEngine()->SetStrokeMode(capMode, joinMode, - miterLimit); + view->GetDrawingEngine()->SetStrokeMode(capMode, joinMode, miterLimit); } static void -set_pen_size(View* view, float size) +set_pen_size(DrawingContext* view, float size) { view->CurrentState()->SetPenSize(size); - view->Window()->GetDrawingEngine()->SetPenSize( - view->CurrentState()->PenSize()); + view->GetDrawingEngine()->SetPenSize(view->CurrentState()->PenSize()); // DrawState::PenSize() returns the scaled pen size, so we // need to use that value to set the drawing engine pen size. } static void -set_fore_color(View* view, rgb_color color) +set_fore_color(DrawingContext* view, rgb_color color) { view->CurrentState()->SetHighColor(color); - view->Window()->GetDrawingEngine()->SetHighColor(color); + view->GetDrawingEngine()->SetHighColor(color); } static void -set_back_color(View* view, rgb_color color) +set_back_color(DrawingContext* view, rgb_color color) { view->CurrentState()->SetLowColor(color); - view->Window()->GetDrawingEngine()->SetLowColor(color); + view->GetDrawingEngine()->SetLowColor(color); } static void -set_stipple_pattern(View* view, pattern p) +set_stipple_pattern(DrawingContext* view, pattern p) { view->CurrentState()->SetPattern(Pattern(p)); - view->Window()->GetDrawingEngine()->SetPattern(p); + view->GetDrawingEngine()->SetPattern(p); } static void -set_scale(View* view, float scale) +set_scale(DrawingContext* view, float scale) { view->CurrentState()->SetScale(scale); - view->Window()->ServerWindow()->ResyncDrawState(); + view->ResyncDrawState(); // Update the drawing engine draw state, since some stuff // (for example the pen size) needs to be recalculated. @@ -684,7 +679,7 @@ set_scale(View* view, float scale) static void -set_font_family(View* view, const char* family) +set_font_family(DrawingContext* view, const char* family) { FontStyle* fontStyle = gFontManager->GetStyleByIndex(family, 0); ServerFont font; @@ -694,7 +689,7 @@ set_font_family(View* view, const char* family) static void -set_font_style(View* view, const char* style) +set_font_style(DrawingContext* view, const char* style) { ServerFont font(view->CurrentState()->Font()); @@ -706,7 +701,7 @@ set_font_style(View* view, const char* style) static void -set_font_spacing(View* view, int32 spacing) +set_font_spacing(DrawingContext* view, int32 spacing) { ServerFont font; font.SetSpacing(spacing); @@ -715,7 +710,7 @@ set_font_spacing(View* view, int32 spacing) static void -set_font_size(View* view, float size) +set_font_size(DrawingContext* view, float size) { ServerFont font; font.SetSize(size); @@ -724,7 +719,7 @@ set_font_size(View* view, float size) static void -set_font_rotate(View* view, float rotation) +set_font_rotate(DrawingContext* view, float rotation) { ServerFont font; font.SetRotation(rotation); @@ -733,7 +728,7 @@ set_font_rotate(View* view, float rotation) static void -set_font_encoding(View* view, int32 encoding) +set_font_encoding(DrawingContext* view, int32 encoding) { ServerFont font; font.SetEncoding(encoding); @@ -742,7 +737,7 @@ set_font_encoding(View* view, int32 encoding) static void -set_font_flags(View* view, int32 flags) +set_font_flags(DrawingContext* view, int32 flags) { ServerFont font; font.SetFlags(flags); @@ -751,7 +746,7 @@ set_font_flags(View* view, int32 flags) static void -set_font_shear(View* view, float shear) +set_font_shear(DrawingContext* view, float shear) { ServerFont font; font.SetShear(shear); @@ -760,7 +755,7 @@ set_font_shear(View* view, float shear) static void -set_font_face(View* view, int32 face) +set_font_face(DrawingContext* view, int32 face) { ServerFont font; font.SetFace(face); @@ -769,7 +764,7 @@ set_font_face(View* view, int32 face) static void -set_blending_mode(View* view, int16 alphaSrcMode, int16 alphaFncMode) +set_blending_mode(DrawingContext* view, int16 alphaSrcMode, int16 alphaFncMode) { view->CurrentState()->SetBlendingMode((source_alpha)alphaSrcMode, (alpha_function)alphaFncMode); @@ -1064,7 +1059,7 @@ ServerPicture::SetFontFromLink(BPrivate::LinkReceiver& link) void -ServerPicture::Play(View* view) +ServerPicture::Play(DrawingContext* target) { // TODO: for now: then change PicturePlayer // to accept a BPositionIO object @@ -1075,7 +1070,7 @@ ServerPicture::Play(View* view) BPrivate::PicturePlayer player(mallocIO->Buffer(), mallocIO->BufferLength(), PictureList::Private(fPictures).AsBList()); player.Play(const_cast(kTableEntries), - sizeof(kTableEntries) / sizeof(void*), view); + sizeof(kTableEntries) / sizeof(void*), target); } diff --git a/src/servers/app/ServerPicture.h b/src/servers/app/ServerPicture.h index 92416202e9..6f27d38c2a 100644 --- a/src/servers/app/ServerPicture.h +++ b/src/servers/app/ServerPicture.h @@ -17,9 +17,10 @@ #include +class BFile; +class DrawingContext; class ServerApp; class View; -class BFile; namespace BPrivate { class LinkReceiver; @@ -48,7 +49,7 @@ public: void SyncState(View* view); void SetFontFromLink(BPrivate::LinkReceiver& link); - void Play(View* view); + void Play(DrawingContext* target); void PushPicture(ServerPicture* picture); ServerPicture* PopPicture(); diff --git a/src/servers/app/View.cpp b/src/servers/app/View.cpp index cbc0aadd88..bbb7616d12 100644 --- a/src/servers/app/View.cpp +++ b/src/servers/app/View.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2008, Haiku, Inc. + * Copyright (c) 2001-2014, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -8,6 +8,7 @@ * Axel Dörfler, axeld@pinc-software.de * Stephan Aßmus * Marcus Overhagen + * Adrien Destugues GetDrawingEngine(); +} + + +ServerPicture* +View::GetPicture(int32 token) const +{ + return Window()->ServerWindow()->App()->GetPicture(token); +} + + +void +View::ResyncDrawState() +{ + return Window()->ServerWindow()->ResyncDrawState(); +} + + +void +View::UpdateCurrentDrawingRegion() +{ + return Window()->ServerWindow()->UpdateCurrentDrawingRegion(); +} + + void View::AddChild(View* view) { @@ -455,58 +483,6 @@ View::SetFlags(uint32 flags) } -void -View::SetDrawingOrigin(BPoint origin) -{ - fDrawState->SetOrigin(origin); - - // rebuild clipping - if (fDrawState->HasClipping()) - RebuildClipping(false); -} - - -BPoint -View::DrawingOrigin() const -{ - BPoint origin(fDrawState->Origin()); - float scale = Scale(); - - origin.x *= scale; - origin.y *= scale; - - return origin; -} - - -void -View::SetScale(float scale) -{ - fDrawState->SetScale(scale); - - // rebuild clipping - if (fDrawState->HasClipping()) - RebuildClipping(false); -} - - -float -View::Scale() const -{ - return CurrentState()->Scale(); -} - - -void -View::SetUserClipping(const BRegion* region) -{ - fDrawState->SetClippingRegion(region); - - // rebuild clipping (for just this view) - RebuildClipping(false); -} - - void View::SetViewBitmap(ServerBitmap* bitmap, IntRect sourceRect, IntRect destRect, int32 resizingMode, int32 options) @@ -788,164 +764,6 @@ View::ConvertFromScreen(BRegion* region) const } -//! converts a point from local *drawing* to screen coordinate system -void -View::ConvertToScreenForDrawing(BPoint* point) const -{ - fDrawState->Transform(point); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(point); -} - - -//! converts a rect from local *drawing* to screen coordinate system -void -View::ConvertToScreenForDrawing(BRect* rect) const -{ - fDrawState->Transform(rect); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(rect); -} - - -//! converts a region from local *drawing* to screen coordinate system -void -View::ConvertToScreenForDrawing(BRegion* region) const -{ - fDrawState->Transform(region); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(region); -} - - -//! converts a gradient from local *drawing* to screen coordinate system -void -View::ConvertToScreenForDrawing(BGradient* gradient) const -{ - switch(gradient->GetType()) { - case BGradient::TYPE_LINEAR: { - BGradientLinear* linear = (BGradientLinear*) gradient; - BPoint start = linear->Start(); - BPoint end = linear->End(); - fDrawState->Transform(&start); - ConvertToScreen(&start); - fDrawState->Transform(&end); - ConvertToScreen(&end); - linear->SetStart(start); - linear->SetEnd(end); - linear->SortColorStopsByOffset(); - break; - } - case BGradient::TYPE_RADIAL: { - BGradientRadial* radial = (BGradientRadial*) gradient; - BPoint center = radial->Center(); - fDrawState->Transform(¢er); - ConvertToScreen(¢er); - radial->SetCenter(center); - radial->SortColorStopsByOffset(); - break; - } - case BGradient::TYPE_RADIAL_FOCUS: { - BGradientRadialFocus* radialFocus = (BGradientRadialFocus*) gradient; - BPoint center = radialFocus->Center(); - BPoint focal = radialFocus->Focal(); - fDrawState->Transform(¢er); - ConvertToScreen(¢er); - fDrawState->Transform(&focal); - ConvertToScreen(&focal); - radialFocus->SetCenter(center); - radialFocus->SetFocal(focal); - radialFocus->SortColorStopsByOffset(); - break; - } - case BGradient::TYPE_DIAMOND: { - BGradientDiamond* diamond = (BGradientDiamond*) gradient; - BPoint center = diamond->Center(); - fDrawState->Transform(¢er); - ConvertToScreen(¢er); - diamond->SetCenter(center); - diamond->SortColorStopsByOffset(); - break; - } - case BGradient::TYPE_CONIC: { - BGradientConic* conic = (BGradientConic*) gradient; - BPoint center = conic->Center(); - fDrawState->Transform(¢er); - ConvertToScreen(¢er); - conic->SetCenter(center); - conic->SortColorStopsByOffset(); - break; - } - case BGradient::TYPE_NONE: { - break; - } - } -} - - -//! converts points from local *drawing* to screen coordinate system -void -View::ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const -{ - // TODO: optimize this, it should be smarter - while (num--) { - *dst = *src; - fDrawState->Transform(dst); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(dst); - src++; - dst++; - } -} - - -//! converts rects from local *drawing* to screen coordinate system -void -View::ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const -{ - // TODO: optimize this, it should be smarter - while (num--) { - *dst = *src; - fDrawState->Transform(dst); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(dst); - src++; - dst++; - } -} - - -//! converts regions from local *drawing* to screen coordinate system -void -View::ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const -{ - // TODO: optimize this, it should be smarter - while (num--) { - *dst = *src; - fDrawState->Transform(dst); - // NOTE: from here on, don't use the - // "*ForDrawing()" versions of the parent! - ConvertToScreen(dst); - src++; - dst++; - } -} - - -//! converts a point from screen to local coordinate system -void -View::ConvertFromScreenForDrawing(BPoint* point) const -{ - ConvertFromScreen(point); - fDrawState->InverseTransform(point); -} - - // #pragma mark - @@ -1257,6 +1075,10 @@ View::PushState() DrawState* newState = fDrawState->PushState(); if (newState) { fDrawState = newState; + // In BeAPI, B_SUBPIXEL_PRECISE is a view flag, and not affected by the + // view state. Our implementation moves it to the draw state, but let's + // be compatible with the API here and make it survive accross state + // changes. fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE); } } @@ -1283,6 +1105,9 @@ View::PopState() } +// #pragma mark - + + void View::SetEventMask(uint32 eventMask, uint32 options) { diff --git a/src/servers/app/View.h b/src/servers/app/View.h index f532023bd2..aa58bfb831 100644 --- a/src/servers/app/View.h +++ b/src/servers/app/View.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2008, Haiku, Inc. + * Copyright (c) 2001-2014, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -8,11 +8,13 @@ * Axel Dörfler, axeld@pinc-software.de * Stephan Aßmus * Marcus Overhagen + * Adrien Destugues */ #ifndef VIEW_H #define VIEW_H +#include "DrawingContext.h" #include "IntRect.h" #include @@ -27,7 +29,6 @@ namespace BPrivate { class PortLink; }; -class DrawState; class DrawingEngine; class Overlay; class Window; @@ -36,8 +37,8 @@ class ServerCursor; class ServerPicture; class BGradient; -class View { - public: +class View: public DrawingContext { + public: View(IntRect frame, IntPoint scrollingOffset, const char* name, int32 token, uint32 resizeMode, uint32 flags); @@ -65,15 +66,6 @@ class View { inline IntPoint ScrollingOffset() const { return fScrollingOffset; } - void SetDrawingOrigin(BPoint origin); - BPoint DrawingOrigin() const; - - void SetScale(float scale); - float Scale() const; - - void SetUserClipping(const BRegion* region); - // region is expected in view coordinates - // converts the given frame up the view hierarchy and // clips to each views bounds void ConvertToVisibleInTopView(IntRect* bounds) const; @@ -82,6 +74,12 @@ class View { virtual void DetachedFromWindow(); ::Window* Window() const { return fWindow; } + // Shorthands for opaque Window access + DrawingEngine* GetDrawingEngine() const; + ServerPicture* GetPicture(int32 token) const; + void ResyncDrawState(); + void UpdateCurrentDrawingRegion(); + // tree stuff void AddChild(View* view); bool RemoveChild(View* view); @@ -112,13 +110,13 @@ class View { void ConvertToParent(IntPoint* point) const; void ConvertToParent(BRect* rect) const; void ConvertToParent(IntRect* rect) const; - void ConvertToParent(BRegion* region) const; + void ConvertToParent(BRegion* region) const; void ConvertFromParent(BPoint* point) const; void ConvertFromParent(IntPoint* point) const; void ConvertFromParent(BRect* rect) const; void ConvertFromParent(IntRect* rect) const; - void ConvertFromParent(BRegion* region) const; + void ConvertFromParent(BRegion* region) const; void ConvertToScreen(BPoint* point) const; void ConvertToScreen(IntPoint* point) const; @@ -132,18 +130,6 @@ class View { void ConvertFromScreen(IntRect* rect) const; void ConvertFromScreen(BRegion* region) const; - void ConvertToScreenForDrawing(BPoint* point) const; - void ConvertToScreenForDrawing(BRect* rect) const; - void ConvertToScreenForDrawing(BRegion* region) const; - void ConvertToScreenForDrawing(BGradient* gradient) const; - - void ConvertToScreenForDrawing(BPoint* dst, const BPoint* src, int32 num) const; - void ConvertToScreenForDrawing(BRect* dst, const BRect* src, int32 num) const; - void ConvertToScreenForDrawing(BRegion* dst, const BRegion* src, int32 num) const; - - void ConvertFromScreenForDrawing(BPoint* point) const; - // used when updating the pen position - void MoveBy(int32 dx, int32 dy, BRegion* dirtyRegion); @@ -174,7 +160,6 @@ class View { void PushState(); void PopState(); - DrawState* CurrentState() const { return fDrawState; } void SetEventMask(uint32 eventMask, uint32 options); uint32 EventMask() const @@ -259,7 +244,6 @@ class View { IntPoint fScrollingOffset; rgb_color fViewColor; - DrawState* fDrawState; ServerBitmap* fViewBitmap; IntRect fBitmapSource; IntRect fBitmapDestination;