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:
parent
98e26ff242
commit
eb43166326
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -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
|
||||
BView::SetDrawingMode(drawing_mode mode)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
@ -690,6 +691,13 @@ DrawState::SetMiterLimit(float limit)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
DrawState::SetFillRule(int32 fillRule)
|
||||
{
|
||||
fFillRule = fillRule;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawState::PrintToStream() const
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: "
|
||||
|
|
|
@ -271,6 +271,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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue