forked from enlightenment/efl
ector : add path cliping feature in FreeType software backend.
This commit is contained in:
parent
cb1226ad41
commit
10dca9f68e
|
@ -147,6 +147,68 @@ SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle *clip, const SW_FT_Span *
|
||||||
return spans;
|
return spans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
|
||||||
|
|
||||||
|
static const
|
||||||
|
SW_FT_Span *_intersect_spans_region(const Shape_Rle_Data *clip, int *currentClip,
|
||||||
|
const SW_FT_Span *spans, const SW_FT_Span *end,
|
||||||
|
SW_FT_Span **outSpans, int available)
|
||||||
|
{
|
||||||
|
SW_FT_Span *out = *outSpans;
|
||||||
|
|
||||||
|
const SW_FT_Span *clipSpans = clip->spans + *currentClip;
|
||||||
|
const SW_FT_Span *clipEnd = clip->spans + clip->size;
|
||||||
|
|
||||||
|
while (available && spans < end ) {
|
||||||
|
if (clipSpans >= clipEnd) {
|
||||||
|
spans = end;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (clipSpans->y > spans->y) {
|
||||||
|
++spans;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (spans->y != clipSpans->y) {
|
||||||
|
++clipSpans;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//assert(spans->y == clipSpans->y);
|
||||||
|
|
||||||
|
int sx1 = spans->x;
|
||||||
|
int sx2 = sx1 + spans->len;
|
||||||
|
int cx1 = clipSpans->x;
|
||||||
|
int cx2 = cx1 + clipSpans->len;
|
||||||
|
|
||||||
|
if (cx1 < sx1 && cx2 < sx1) {
|
||||||
|
++clipSpans;
|
||||||
|
continue;
|
||||||
|
} else if (sx1 < cx1 && sx2 < cx1) {
|
||||||
|
++spans;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int x = MAX(sx1, cx1);
|
||||||
|
int len = MIN(sx2, cx2) - x;
|
||||||
|
if (len) {
|
||||||
|
out->x = MAX(sx1, cx1);
|
||||||
|
out->len = MIN(sx2, cx2) - out->x;
|
||||||
|
out->y = spans->y;
|
||||||
|
out->coverage = _div_255(spans->coverage * clipSpans->coverage);
|
||||||
|
++out;
|
||||||
|
--available;
|
||||||
|
}
|
||||||
|
if (sx2 < cx2) {
|
||||||
|
++spans;
|
||||||
|
} else {
|
||||||
|
++clipSpans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*outSpans = out;
|
||||||
|
*currentClip = clipSpans - clip->spans;
|
||||||
|
return spans;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_span_fill_clipRect(int spanCount, const SW_FT_Span *spans, void *userData)
|
_span_fill_clipRect(int spanCount, const SW_FT_Span *spans, void *userData)
|
||||||
{
|
{
|
||||||
|
@ -167,8 +229,6 @@ _span_fill_clipRect(int spanCount, const SW_FT_Span *spans, void *userData)
|
||||||
tmpRect.y = rect->y - fillData->offy;
|
tmpRect.y = rect->y - fillData->offy;
|
||||||
tmpRect.w = rect->w;
|
tmpRect.w = rect->w;
|
||||||
tmpRect.h = rect->h;
|
tmpRect.h = rect->h;
|
||||||
//printf("Clip after Offset : %d , %d ,%d , %d\n",tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h);
|
|
||||||
//printf("Offset = %d , %d \n", fillData->offx, fillData->offy);
|
|
||||||
const SW_FT_Span *end = spans + spanCount;
|
const SW_FT_Span *end = spans + spanCount;
|
||||||
|
|
||||||
while (spans < end)
|
while (spans < end)
|
||||||
|
@ -181,6 +241,27 @@ _span_fill_clipRect(int spanCount, const SW_FT_Span *spans, void *userData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_span_fill_clipPath(int spanCount, const SW_FT_Span *spans, void *userData)
|
||||||
|
{
|
||||||
|
const int NSPANS = 256;
|
||||||
|
int current_clip = 0;
|
||||||
|
SW_FT_Span cspans[NSPANS];
|
||||||
|
Span_Data *fillData = (Span_Data *) userData;
|
||||||
|
Clip_Data clip = fillData->clip;
|
||||||
|
|
||||||
|
//TODO take clip path offset into account.
|
||||||
|
|
||||||
|
const SW_FT_Span *end = spans + spanCount;
|
||||||
|
while (spans < end)
|
||||||
|
{
|
||||||
|
SW_FT_Span *clipped = cspans;
|
||||||
|
spans = _intersect_spans_region(clip.path, ¤t_clip, spans, end, &clipped, NSPANS);
|
||||||
|
if (clipped - cspans)
|
||||||
|
fillData->unclipped_blend(clipped - cspans, cspans, fillData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_adjust_span_fill_methods(Span_Data *spdata)
|
_adjust_span_fill_methods(Span_Data *spdata)
|
||||||
{
|
{
|
||||||
|
@ -216,7 +297,7 @@ _adjust_span_fill_methods(Span_Data *spdata)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
spdata->blend = &_span_fill_clipRect; //TODO change when do path clipping
|
spdata->blend = &_span_fill_clipPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue