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.
This commit is contained in:
@@ -261,6 +261,14 @@ enum cap_mode {
|
|||||||
const float B_DEFAULT_MITER_LIMIT = 10.0F;
|
const float B_DEFAULT_MITER_LIMIT = 10.0F;
|
||||||
|
|
||||||
|
|
||||||
|
// Polygon filling rules
|
||||||
|
|
||||||
|
enum {
|
||||||
|
B_EVEN_ODD = 0,
|
||||||
|
B_NONZERO
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Bitmap and overlay constants
|
// Bitmap and overlay constants
|
||||||
|
|
||||||
enum bitmap_tiling {
|
enum bitmap_tiling {
|
||||||
|
|||||||
@@ -282,6 +282,9 @@ public:
|
|||||||
cap_mode LineCapMode() const;
|
cap_mode LineCapMode() const;
|
||||||
float LineMiterLimit() const;
|
float LineMiterLimit() const;
|
||||||
|
|
||||||
|
void SetFillRule(int32 rule);
|
||||||
|
int32 FillRule() const;
|
||||||
|
|
||||||
void SetOrigin(BPoint pt);
|
void SetOrigin(BPoint pt);
|
||||||
void SetOrigin(float x, float y);
|
void SetOrigin(float x, float y);
|
||||||
BPoint Origin() const;
|
BPoint Origin() const;
|
||||||
|
|||||||
@@ -345,6 +345,10 @@ enum {
|
|||||||
AS_VIEW_SET_TRANSFORM,
|
AS_VIEW_SET_TRANSFORM,
|
||||||
AS_VIEW_GET_TRANSFORM,
|
AS_VIEW_GET_TRANSFORM,
|
||||||
|
|
||||||
|
// Polygon filling rules
|
||||||
|
AS_VIEW_SET_FILL_RULE,
|
||||||
|
AS_VIEW_GET_FILL_RULE,
|
||||||
|
|
||||||
AS_LAST_CODE
|
AS_LAST_CODE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,9 @@ enum {
|
|||||||
B_VIEW_VIEW_COLOR_BIT = 0x00010000,
|
B_VIEW_VIEW_COLOR_BIT = 0x00010000,
|
||||||
B_VIEW_PATTERN_BIT = 0x00020000,
|
B_VIEW_PATTERN_BIT = 0x00020000,
|
||||||
B_VIEW_TRANSFORM_BIT = 0x00040000,
|
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
|
// these used for archiving only
|
||||||
B_VIEW_RESIZE_BIT = 0x00001000,
|
B_VIEW_RESIZE_BIT = 0x00001000,
|
||||||
@@ -123,6 +124,9 @@ class ViewState {
|
|||||||
cap_mode line_cap;
|
cap_mode line_cap;
|
||||||
float miter_limit;
|
float miter_limit;
|
||||||
|
|
||||||
|
// fill rule
|
||||||
|
int32 fill_rule;
|
||||||
|
|
||||||
// alpha blending
|
// alpha blending
|
||||||
source_alpha alpha_source_mode;
|
source_alpha alpha_source_mode;
|
||||||
alpha_function alpha_function_mode;
|
alpha_function alpha_function_mode;
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ ViewState::ViewState()
|
|||||||
line_join = B_MITER_JOIN;
|
line_join = B_MITER_JOIN;
|
||||||
line_cap = B_BUTT_CAP;
|
line_cap = B_BUTT_CAP;
|
||||||
miter_limit = B_DEFAULT_MITER_LIMIT;
|
miter_limit = B_DEFAULT_MITER_LIMIT;
|
||||||
|
fill_rule = B_NONZERO;
|
||||||
|
|
||||||
alpha_source_mode = B_PIXEL_ALPHA;
|
alpha_source_mode = B_PIXEL_ALPHA;
|
||||||
alpha_function_mode = B_ALPHA_OVERLAY;
|
alpha_function_mode = B_ALPHA_OVERLAY;
|
||||||
@@ -494,6 +495,10 @@ BView::BView(BMessage* archive)
|
|||||||
&& archive->FindFloat("_lmmiter", &lineMiter) == B_OK)
|
&& archive->FindFloat("_lmmiter", &lineMiter) == B_OK)
|
||||||
SetLineMode((cap_mode)lineCap, (join_mode)lineJoin, lineMiter);
|
SetLineMode((cap_mode)lineCap, (join_mode)lineJoin, lineMiter);
|
||||||
|
|
||||||
|
int16 fillRule;
|
||||||
|
if (archive->FindInt16("_fillrule", &fillRule) == B_OK)
|
||||||
|
SetFillRule(fillRule);
|
||||||
|
|
||||||
int16 alphaBlend;
|
int16 alphaBlend;
|
||||||
int16 modeBlend;
|
int16 modeBlend;
|
||||||
if (archive->FindInt16("_blend", 0, &alphaBlend) == B_OK
|
if (archive->FindInt16("_blend", 0, &alphaBlend) == B_OK
|
||||||
@@ -617,6 +622,9 @@ BView::Archive(BMessage* data, bool deep) const
|
|||||||
ret = data->AddFloat("_lmmiter", LineMiterLimit());
|
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) {
|
if (ret == B_OK && (fState->archiving_flags & B_VIEW_BLENDING_BIT) != 0) {
|
||||||
source_alpha alphaSourceMode;
|
source_alpha alphaSourceMode;
|
||||||
alpha_function alphaFunctionMode;
|
alpha_function alphaFunctionMode;
|
||||||
@@ -1992,6 +2000,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
|
void
|
||||||
BView::SetDrawingMode(drawing_mode mode)
|
BView::SetDrawingMode(drawing_mode mode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ DrawState::DrawState()
|
|||||||
fLineCapMode(B_BUTT_CAP),
|
fLineCapMode(B_BUTT_CAP),
|
||||||
fLineJoinMode(B_MITER_JOIN),
|
fLineJoinMode(B_MITER_JOIN),
|
||||||
fMiterLimit(B_DEFAULT_MITER_LIMIT),
|
fMiterLimit(B_DEFAULT_MITER_LIMIT),
|
||||||
|
fFillRule(B_NONZERO),
|
||||||
fPreviousState(NULL)
|
fPreviousState(NULL)
|
||||||
{
|
{
|
||||||
fUnscaledFontSize = fFont.Size();
|
fUnscaledFontSize = fFont.Size();
|
||||||
@@ -690,6 +691,13 @@ DrawState::SetMiterLimit(float limit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DrawState::SetFillRule(int32 fillRule)
|
||||||
|
{
|
||||||
|
fFillRule = fillRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DrawState::PrintToStream() const
|
DrawState::PrintToStream() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -144,6 +144,10 @@ public:
|
|||||||
float MiterLimit() const
|
float MiterLimit() const
|
||||||
{ return fMiterLimit; }
|
{ return fMiterLimit; }
|
||||||
|
|
||||||
|
void SetFillRule(int32 fillRule);
|
||||||
|
int32 FillRule() const
|
||||||
|
{ return fFillRule; }
|
||||||
|
|
||||||
// convenience functions
|
// convenience functions
|
||||||
void PrintToStream() const;
|
void PrintToStream() const;
|
||||||
|
|
||||||
@@ -192,6 +196,7 @@ protected:
|
|||||||
cap_mode fLineCapMode;
|
cap_mode fLineCapMode;
|
||||||
join_mode fLineJoinMode;
|
join_mode fLineJoinMode;
|
||||||
float fMiterLimit;
|
float fMiterLimit;
|
||||||
|
int32 fFillRule;
|
||||||
// "internal", used to calculate the size
|
// "internal", used to calculate the size
|
||||||
// of the font (again) when the scale changes
|
// of the font (again) when the scale changes
|
||||||
float fUnscaledFontSize;
|
float fUnscaledFontSize;
|
||||||
|
|||||||
@@ -256,6 +256,8 @@ string_for_message_code(uint32 code, BString& string)
|
|||||||
CODE(AS_VIEW_SCROLL);
|
CODE(AS_VIEW_SCROLL);
|
||||||
CODE(AS_VIEW_SET_LINE_MODE);
|
CODE(AS_VIEW_SET_LINE_MODE);
|
||||||
CODE(AS_VIEW_GET_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_PUSH_STATE);
|
||||||
CODE(AS_VIEW_POP_STATE);
|
CODE(AS_VIEW_POP_STATE);
|
||||||
CODE(AS_VIEW_SET_SCALE);
|
CODE(AS_VIEW_SET_SCALE);
|
||||||
|
|||||||
@@ -1529,6 +1529,31 @@ fDesktop->LockSingleWindow();
|
|||||||
|
|
||||||
break;
|
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:
|
case AS_VIEW_PUSH_STATE:
|
||||||
{
|
{
|
||||||
DTRACE(("ServerWindow %s: Message AS_VIEW_PUSH_STATE: View: "
|
DTRACE(("ServerWindow %s: Message AS_VIEW_PUSH_STATE: View: "
|
||||||
|
|||||||
@@ -271,6 +271,13 @@ DrawingEngine::SetStrokeMode(cap_mode lineCap, join_mode joinMode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DrawingEngine::SetFillRule(int32 fillRule)
|
||||||
|
{
|
||||||
|
fPainter->SetFillRule(fillRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DrawingEngine::SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc)
|
DrawingEngine::SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public:
|
|||||||
virtual void SetPenSize(float size);
|
virtual void SetPenSize(float size);
|
||||||
virtual void SetStrokeMode(cap_mode lineCap, join_mode joinMode,
|
virtual void SetStrokeMode(cap_mode lineCap, join_mode joinMode,
|
||||||
float miterLimit);
|
float miterLimit);
|
||||||
|
virtual void SetFillRule(int32 fillRule);
|
||||||
virtual void SetPattern(const struct pattern& pattern);
|
virtual void SetPattern(const struct pattern& pattern);
|
||||||
virtual void SetDrawingMode(drawing_mode mode);
|
virtual void SetDrawingMode(drawing_mode mode);
|
||||||
virtual void SetDrawingMode(drawing_mode mode,
|
virtual void SetDrawingMode(drawing_mode mode,
|
||||||
|
|||||||
@@ -199,6 +199,7 @@ Painter::Painter()
|
|||||||
fLineCapMode(B_BUTT_CAP),
|
fLineCapMode(B_BUTT_CAP),
|
||||||
fLineJoinMode(B_MITER_JOIN),
|
fLineJoinMode(B_MITER_JOIN),
|
||||||
fMiterLimit(B_DEFAULT_MITER_LIMIT),
|
fMiterLimit(B_DEFAULT_MITER_LIMIT),
|
||||||
|
fFillRule(B_NONZERO),
|
||||||
|
|
||||||
fPatternHandler(),
|
fPatternHandler(),
|
||||||
fTextRenderer(fSubpixRenderer, fRenderer, fRendererBin, fUnpackedScanline,
|
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
|
// SetPattern
|
||||||
void
|
void
|
||||||
Painter::SetPattern(const pattern& p, bool drawingText)
|
Painter::SetPattern(const pattern& p, bool drawingText)
|
||||||
@@ -2827,16 +2835,22 @@ Painter::_RasterizePath(VertexSource& path) const
|
|||||||
if (fMaskedUnpackedScanline != NULL) {
|
if (fMaskedUnpackedScanline != NULL) {
|
||||||
// TODO: we can't do both alpha-masking and subpixel AA.
|
// TODO: we can't do both alpha-masking and subpixel AA.
|
||||||
fRasterizer.reset();
|
fRasterizer.reset();
|
||||||
|
fRasterizer.filling_rule(
|
||||||
|
fFillRule == B_EVEN_ODD ? agg::fill_even_odd : agg::fill_non_zero);
|
||||||
fRasterizer.add_path(path);
|
fRasterizer.add_path(path);
|
||||||
agg::render_scanlines(fRasterizer, *fMaskedUnpackedScanline,
|
agg::render_scanlines(fRasterizer, *fMaskedUnpackedScanline,
|
||||||
fRenderer);
|
fRenderer);
|
||||||
} else if (gSubpixelAntialiasing) {
|
} else if (gSubpixelAntialiasing) {
|
||||||
fSubpixRasterizer.reset();
|
fSubpixRasterizer.reset();
|
||||||
|
fSubpixRasterizer.filling_rule(
|
||||||
|
fFillRule == B_EVEN_ODD ? agg::fill_even_odd : agg::fill_non_zero);
|
||||||
fSubpixRasterizer.add_path(path);
|
fSubpixRasterizer.add_path(path);
|
||||||
agg::render_scanlines(fSubpixRasterizer,
|
agg::render_scanlines(fSubpixRasterizer,
|
||||||
fSubpixPackedScanline, fSubpixRenderer);
|
fSubpixPackedScanline, fSubpixRenderer);
|
||||||
} else {
|
} else {
|
||||||
fRasterizer.reset();
|
fRasterizer.reset();
|
||||||
|
fRasterizer.filling_rule(
|
||||||
|
fFillRule == B_EVEN_ODD ? agg::fill_even_odd : agg::fill_non_zero);
|
||||||
fRasterizer.add_path(path);
|
fRasterizer.add_path(path);
|
||||||
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
|
agg::render_scanlines(fRasterizer, fPackedScanline, fRenderer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public:
|
|||||||
{ return fPenSize; }
|
{ return fPenSize; }
|
||||||
void SetStrokeMode(cap_mode lineCap,
|
void SetStrokeMode(cap_mode lineCap,
|
||||||
join_mode joinMode, float miterLimit);
|
join_mode joinMode, float miterLimit);
|
||||||
|
void SetFillRule(int32 fillRule);
|
||||||
void SetPattern(const pattern& p,
|
void SetPattern(const pattern& p,
|
||||||
bool drawingText = false);
|
bool drawingText = false);
|
||||||
inline pattern Pattern() const
|
inline pattern Pattern() const
|
||||||
@@ -394,6 +395,7 @@ private:
|
|||||||
cap_mode fLineCapMode;
|
cap_mode fLineCapMode;
|
||||||
join_mode fLineJoinMode;
|
join_mode fLineJoinMode;
|
||||||
float fMiterLimit;
|
float fMiterLimit;
|
||||||
|
int32 fFillRule;
|
||||||
|
|
||||||
PatternHandler fPatternHandler;
|
PatternHandler fPatternHandler;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user