[haiku-commits] haiku: hrev47005 - src/kits/interface src/servers/app src/servers/app/drawing/Painter headers/private/interface src/servers/app/drawing

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 11 Mar 2014 17:26:24 +0100 (CET)

hrev47005 adds 1 changeset to branch 'master'
old head: 98e26ff2422c423dca23e08628b5f723727e5d42
new head: eb431663264ef319e72b492801fb867b5d71910b
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=eb43166+%5E98e26ff

----------------------------------------------------------------------------

eb43166: app_server & interface kit: support fill rules.
  
  * BView gets SetFillRule/FillRule methods. The fill rule is part of the
  view state.
  * The B_NONZERO rule is the default. This is what we implemented before.
  * The B_EVEN_ODD rule is the other common possibility for this, and
  we need to support it to help WebKit to render properly.

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev47005
Commit:      eb431663264ef319e72b492801fb867b5d71910b
URL:         http://cgit.haiku-os.org/haiku/commit/?id=eb43166
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Tue Mar 11 16:23:32 2014 UTC

----------------------------------------------------------------------------

13 files changed, 137 insertions(+), 1 deletion(-)
headers/os/interface/InterfaceDefs.h        |  8 ++++
headers/os/interface/View.h                 |  3 ++
headers/private/app/ServerProtocol.h        |  4 ++
headers/private/interface/ViewPrivate.h     |  6 ++-
src/kits/interface/View.cpp                 | 53 +++++++++++++++++++++++++
src/servers/app/DrawState.cpp               |  8 ++++
src/servers/app/DrawState.h                 |  5 +++
src/servers/app/ProfileMessageSupport.cpp   |  2 +
src/servers/app/ServerWindow.cpp            | 25 ++++++++++++
src/servers/app/drawing/DrawingEngine.cpp   |  7 ++++
src/servers/app/drawing/DrawingEngine.h     |  1 +
src/servers/app/drawing/Painter/Painter.cpp | 14 +++++++
src/servers/app/drawing/Painter/Painter.h   |  2 +

----------------------------------------------------------------------------

diff --git a/headers/os/interface/InterfaceDefs.h 
b/headers/os/interface/InterfaceDefs.h
index b1808cd..accef2c 100644
--- a/headers/os/interface/InterfaceDefs.h
+++ b/headers/os/interface/InterfaceDefs.h
@@ -261,6 +261,14 @@ enum cap_mode {
 const float B_DEFAULT_MITER_LIMIT = 10.0F;
 
 
+// Polygon filling rules
+
+enum {
+       B_EVEN_ODD = 0,
+       B_NONZERO
+};
+
+
 // Bitmap and overlay constants
 
 enum bitmap_tiling {
diff --git a/headers/os/interface/View.h b/headers/os/interface/View.h
index bda8acd..84a63b0 100644
--- a/headers/os/interface/View.h
+++ b/headers/os/interface/View.h
@@ -282,6 +282,9 @@ public:
                        cap_mode                        LineCapMode() const;
                        float                           LineMiterLimit() const;
 
+                       void                            SetFillRule(int32 rule);
+                       int32                           FillRule() const;
+
                        void                            SetOrigin(BPoint pt);
                        void                            SetOrigin(float x, 
float y);
                        BPoint                          Origin() const;
diff --git a/headers/private/app/ServerProtocol.h 
b/headers/private/app/ServerProtocol.h
index 782a578..e85f774 100644
--- a/headers/private/app/ServerProtocol.h
+++ b/headers/private/app/ServerProtocol.h
@@ -345,6 +345,10 @@ enum {
        AS_VIEW_SET_TRANSFORM,
        AS_VIEW_GET_TRANSFORM,
 
+       // Polygon filling rules
+       AS_VIEW_SET_FILL_RULE,
+       AS_VIEW_GET_FILL_RULE,
+
        AS_LAST_CODE
 };
 
diff --git a/headers/private/interface/ViewPrivate.h 
b/headers/private/interface/ViewPrivate.h
index 4be0f77..a9073d4 100644
--- a/headers/private/interface/ViewPrivate.h
+++ b/headers/private/interface/ViewPrivate.h
@@ -40,8 +40,9 @@ enum {
        B_VIEW_VIEW_COLOR_BIT           = 0x00010000,
        B_VIEW_PATTERN_BIT                      = 0x00020000,
        B_VIEW_TRANSFORM_BIT            = 0x00040000,
+       B_VIEW_FILL_RULE_BIT            = 0x00080000,
 
-       B_VIEW_ALL_BITS                         = 0x0007ffff,
+       B_VIEW_ALL_BITS                         = 0x000fffff,
 
        // these used for archiving only
        B_VIEW_RESIZE_BIT                       = 0x00001000,
@@ -123,6 +124,9 @@ class ViewState {
                cap_mode                        line_cap;
                float                           miter_limit;
 
+               // fill rule
+               int32                           fill_rule;
+
                // alpha blending
                source_alpha            alpha_source_mode;
                alpha_function          alpha_function_mode;
diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp
index 9aaae85..c7395dd 100644
--- a/src/kits/interface/View.cpp
+++ b/src/kits/interface/View.cpp
@@ -149,6 +149,7 @@ ViewState::ViewState()
        line_join = B_MITER_JOIN;
        line_cap = B_BUTT_CAP;
        miter_limit = B_DEFAULT_MITER_LIMIT;
+       fill_rule = B_NONZERO;
 
        alpha_source_mode = B_PIXEL_ALPHA;
        alpha_function_mode = B_ALPHA_OVERLAY;
@@ -494,6 +495,10 @@ BView::BView(BMessage* archive)
                && archive->FindFloat("_lmmiter", &lineMiter) == B_OK)
                SetLineMode((cap_mode)lineCap, (join_mode)lineJoin, lineMiter);
 
+       int16 fillRule;
+       if (archive->FindInt16("_fillrule", &fillRule) == B_OK)
+               SetFillRule(fillRule);
+
        int16 alphaBlend;
        int16 modeBlend;
        if (archive->FindInt16("_blend", 0, &alphaBlend) == B_OK
@@ -617,6 +622,9 @@ BView::Archive(BMessage* data, bool deep) const
                        ret = data->AddFloat("_lmmiter", LineMiterLimit());
        }
 
+       if (ret == B_OK && (fState->archiving_flags & B_VIEW_FILL_RULE_BIT) != 
0)
+               ret = data->AddInt16("_fillrule", (int16)FillRule());
+
        if (ret == B_OK && (fState->archiving_flags & B_VIEW_BLENDING_BIT) != 
0) {
                source_alpha alphaSourceMode;
                alpha_function alphaFunctionMode;
@@ -1993,6 +2001,51 @@ BView::LineMiterLimit() const
 
 
 void
+BView::SetFillRule(int32 fillRule)
+{
+       if (fState->IsValid(B_VIEW_FILL_RULE_BIT) && fillRule == 
fState->fill_rule)
+               return;
+
+       if (fOwner) {
+               _CheckLockAndSwitchCurrent();
+
+               fOwner->fLink->StartMessage(AS_VIEW_SET_FILL_RULE);
+               fOwner->fLink->Attach<int32>(fillRule);
+
+               fState->valid_flags |= B_VIEW_FILL_RULE_BIT;
+       }
+
+       fState->fill_rule = fillRule;
+
+       fState->archiving_flags |= B_VIEW_FILL_RULE_BIT;
+}
+
+
+int32
+BView::FillRule() const
+{
+       if (!fState->IsValid(B_VIEW_FILL_RULE_BIT) && fOwner) {
+               _CheckLockAndSwitchCurrent();
+
+               fOwner->fLink->StartMessage(AS_VIEW_GET_FILL_RULE);
+
+               int32 code;
+               if (fOwner->fLink->FlushWithReply(code) == B_OK && code == 
B_OK) {
+
+                       int32 fillRule;
+                       fOwner->fLink->Read<int32>(&fillRule);
+
+                       fState->fill_rule = fillRule;
+               }
+
+               fState->valid_flags |= B_VIEW_FILL_RULE_BIT;
+       }
+
+       return fState->fill_rule;
+}
+
+
+void
 BView::SetDrawingMode(drawing_mode mode)
 {
        if (fState->IsValid(B_VIEW_DRAWING_MODE_BIT)
diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp
index c5b5ca3..6d1dd32 100644
--- a/src/servers/app/DrawState.cpp
+++ b/src/servers/app/DrawState.cpp
@@ -55,6 +55,7 @@ DrawState::DrawState()
        fLineCapMode(B_BUTT_CAP),
        fLineJoinMode(B_MITER_JOIN),
        fMiterLimit(B_DEFAULT_MITER_LIMIT),
+       fFillRule(B_NONZERO),
        fPreviousState(NULL)
 {
        fUnscaledFontSize = fFont.Size();
@@ -691,6 +692,13 @@ DrawState::SetMiterLimit(float limit)
 
 
 void
+DrawState::SetFillRule(int32 fillRule)
+{
+       fFillRule = fillRule;
+}
+
+
+void
 DrawState::PrintToStream() const
 {
        printf("\t Origin: (%.1f, %.1f)\n", fOrigin.x, fOrigin.y);
diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h
index 58ca037..48508ed 100644
--- a/src/servers/app/DrawState.h
+++ b/src/servers/app/DrawState.h
@@ -144,6 +144,10 @@ public:
                float                           MiterLimit() const
                                                                { return 
fMiterLimit; }
 
+               void                            SetFillRule(int32 fillRule);
+               int32                           FillRule() const
+                                                               { return 
fFillRule; }
+
                                                        // convenience functions
                void                            PrintToStream() const;
 
@@ -192,6 +196,7 @@ protected:
                cap_mode                        fLineCapMode;
                join_mode                       fLineJoinMode;
                float                           fMiterLimit;
+               int32                           fFillRule;
                // "internal", used to calculate the size
                // of the font (again) when the scale changes
                float                           fUnscaledFontSize;
diff --git a/src/servers/app/ProfileMessageSupport.cpp 
b/src/servers/app/ProfileMessageSupport.cpp
index 519ebbf..1dbb357 100644
--- a/src/servers/app/ProfileMessageSupport.cpp
+++ b/src/servers/app/ProfileMessageSupport.cpp
@@ -256,6 +256,8 @@ string_for_message_code(uint32 code, BString& string)
                CODE(AS_VIEW_SCROLL);
                CODE(AS_VIEW_SET_LINE_MODE);
                CODE(AS_VIEW_GET_LINE_MODE);
+               CODE(AS_VIEW_SET_FILL_RULE);
+               CODE(AS_VIEW_GET_FILL_RULE);
                CODE(AS_VIEW_PUSH_STATE);
                CODE(AS_VIEW_POP_STATE);
                CODE(AS_VIEW_SET_SCALE);
diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp
index fdeb467..88d1c02 100644
--- a/src/servers/app/ServerWindow.cpp
+++ b/src/servers/app/ServerWindow.cpp
@@ -1529,6 +1529,31 @@ fDesktop->LockSingleWindow();
 
                        break;
                }
+               case AS_VIEW_SET_FILL_RULE:
+               {
+                       DTRACE(("ServerWindow %s: Message 
AS_VIEW_SET_FILL_RULE: "
+                               "View: %s\n", Title(), fCurrentView->Name()));
+                       int32 fillRule;
+                       if (link.Read<int32>(&fillRule) != B_OK)
+                               break;
+
+                       fCurrentView->CurrentState()->SetFillRule(fillRule);
+                       fWindow->GetDrawingEngine()->SetFillRule(fillRule);
+
+                       break;
+               }
+               case AS_VIEW_GET_FILL_RULE:
+               {
+                       DTRACE(("ServerWindow %s: Message 
AS_VIEW_GET_FILL_RULE: "
+                               "View: %s\n", Title(), fCurrentView->Name()));
+                       int32 fillRule = 
fCurrentView->CurrentState()->FillRule();
+
+                       fLink.StartMessage(B_OK);
+                       fLink.Attach<int32>(fillRule);
+                       fLink.Flush();
+
+                       break;
+               }
                case AS_VIEW_PUSH_STATE:
                {
                        DTRACE(("ServerWindow %s: Message AS_VIEW_PUSH_STATE: 
View: "
diff --git a/src/servers/app/drawing/DrawingEngine.cpp 
b/src/servers/app/drawing/DrawingEngine.cpp
index 3fdc48f..e37ad03 100644
--- a/src/servers/app/drawing/DrawingEngine.cpp
+++ b/src/servers/app/drawing/DrawingEngine.cpp
@@ -272,6 +272,13 @@ DrawingEngine::SetStrokeMode(cap_mode lineCap, join_mode 
joinMode,
 
 
 void
+DrawingEngine::SetFillRule(int32 fillRule)
+{
+       fPainter->SetFillRule(fillRule);
+}
+
+
+void
 DrawingEngine::SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc)
 {
        fPainter->SetBlendingMode(srcAlpha, alphaFunc);
diff --git a/src/servers/app/drawing/DrawingEngine.h 
b/src/servers/app/drawing/DrawingEngine.h
index ce89487..dd15db2 100644
--- a/src/servers/app/drawing/DrawingEngine.h
+++ b/src/servers/app/drawing/DrawingEngine.h
@@ -76,6 +76,7 @@ public:
        virtual void                    SetPenSize(float size);
        virtual void                    SetStrokeMode(cap_mode lineCap, 
join_mode joinMode,
                                                                float 
miterLimit);
+       virtual void                    SetFillRule(int32 fillRule);
        virtual void                    SetPattern(const struct pattern& 
pattern);
        virtual void                    SetDrawingMode(drawing_mode mode);
        virtual void                    SetDrawingMode(drawing_mode mode,
diff --git a/src/servers/app/drawing/Painter/Painter.cpp 
b/src/servers/app/drawing/Painter/Painter.cpp
index 2300d6c..95d5398 100644
--- a/src/servers/app/drawing/Painter/Painter.cpp
+++ b/src/servers/app/drawing/Painter/Painter.cpp
@@ -199,6 +199,7 @@ Painter::Painter()
        fLineCapMode(B_BUTT_CAP),
        fLineJoinMode(B_MITER_JOIN),
        fMiterLimit(B_DEFAULT_MITER_LIMIT),
+       fFillRule(B_NONZERO),
 
        fPatternHandler(),
        fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, 
fUnpackedScanline,
@@ -423,6 +424,13 @@ Painter::SetStrokeMode(cap_mode lineCap, join_mode 
joinMode, float miterLimit)
 }
 
 
+void
+Painter::SetFillRule(int32 fillRule)
+{
+       fFillRule = fillRule;
+}
+
+
 // SetPattern
 void
 Painter::SetPattern(const pattern& p, bool drawingText)
@@ -2827,16 +2835,22 @@ Painter::_RasterizePath(VertexSource& path) const
        if (fMaskedUnpackedScanline != NULL) {
                // TODO: we can't do both alpha-masking and subpixel AA.
                fRasterizer.reset();
+               fRasterizer.filling_rule(
+                       fFillRule == B_EVEN_ODD ? agg::fill_even_odd : 
agg::fill_non_zero);
                fRasterizer.add_path(path);
                agg::render_scanlines(fRasterizer, *fMaskedUnpackedScanline,
                        fRenderer);
        } else if (gSubpixelAntialiasing) {
                fSubpixRasterizer.reset();
+               fSubpixRasterizer.filling_rule(
+                       fFillRule == B_EVEN_ODD ? agg::fill_even_odd : 
agg::fill_non_zero);
                fSubpixRasterizer.add_path(path);
                agg::render_scanlines(fSubpixRasterizer,
                        fSubpixPackedScanline, fSubpixRenderer);
        } else {
                fRasterizer.reset();
+               fRasterizer.filling_rule(
+                       fFillRule == B_EVEN_ODD ? agg::fill_even_odd : 
agg::fill_non_zero);
                fRasterizer.add_path(path);
                agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
        }
diff --git a/src/servers/app/drawing/Painter/Painter.h 
b/src/servers/app/drawing/Painter/Painter.h
index 5042ed9..b2ccc49 100644
--- a/src/servers/app/drawing/Painter/Painter.h
+++ b/src/servers/app/drawing/Painter/Painter.h
@@ -81,6 +81,7 @@ public:
                                                                        { 
return fPenSize; }
                        void                            SetStrokeMode(cap_mode 
lineCap,
                                                                        
join_mode joinMode, float miterLimit);
+                       void                            SetFillRule(int32 
fillRule);
                        void                            SetPattern(const 
pattern& p,
                                                                        bool 
drawingText = false);
        inline  pattern                         Pattern() const
@@ -394,6 +395,7 @@ private:
                        cap_mode                        fLineCapMode;
                        join_mode                       fLineJoinMode;
                        float                           fMiterLimit;
+                       int32                           fFillRule;
 
                        PatternHandler          fPatternHandler;
 


Other related posts: