SW_FT_Outline outline;
SW_FT_BBox clip_box;
+ int bound_left;
+ int bound_top;
+ int bound_right;
+ int bound_bottom;
+
SW_FT_Span gray_spans[SW_FT_MAX_GRAY_SPANS];
int num_gray_spans;
ras.area = 0;
ras.cover = 0;
ras.invalid = 1;
+
+ ras.bound_left = INT_MAX;
+ ras.bound_top = INT_MAX;
+ ras.bound_right = INT_MIN;
+ ras.bound_bottom = INT_MIN;
}
/*************************************************************************/
SW_FT_Span* span;
int count;
+ // update bounding box.
+ if (x < ras.bound_left) ras.bound_left = x;
+ if (y < ras.bound_top) ras.bound_top = y;
+ if (y > ras.bound_bottom) ras.bound_bottom = y;
+ if (x + acount > ras.bound_right) ras.bound_right = x + acount;
+
/* see whether we can add this span to the current list */
count = ras.num_gray_spans;
span = ras.gray_spans + count - 1;
ras.render_span = (SW_FT_Raster_Span_Func)params->gray_spans;
ras.render_span_data = params->user;
- return gray_convert_glyph(RAS_VAR);
+ gray_convert_glyph(RAS_VAR);
+ params->bbox_cb(ras.bound_left, ras.bound_top,
+ ras.bound_right - ras.bound_left,
+ ras.bound_bottom - ras.bound_top + 1, params->user);
+ return 1;
}
/**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/
const SW_FT_Span* spans,
void* user );
+ typedef void
+ (*SW_FT_BboxFunc)( int x, int y, int w, int h,
+ void* user);
+
#define SW_FT_Raster_Span_Func SW_FT_SpanFunc
const void* source;
int flags;
SW_FT_SpanFunc gray_spans;
+ SW_FT_BboxFunc bbox_cb;
void* user;
SW_FT_BBox clip_box;
rle->addSpan(rleSpan, count);
}
+static void bboxCb(int x, int y, int w, int h, void *user)
+{
+ VRle * rle = (VRle *)user;
+ rle->setBoundingRect({x, y, w, h});
+}
+
struct RleTask {
std::promise<VRle> sender;
VPath path;
params.flags = SW_FT_RASTER_FLAG_DIRECT | SW_FT_RASTER_FLAG_AA;
params.gray_spans = &rleGenerationCb;
+ params.bbox_cb = &bboxCb;
params.user = &rle;
params.source = &outRef.ft;
}
// compute rle
sw_ft_grays_raster.raster_render(nullptr, ¶ms);
- // update bounding box.
- rle.boundingRect();
}
VRle RleTask::operator()(FTOutline &outRef, SW_FT_Stroker &stroker)
return mBbox;
}
+void VRle::VRleData::setBbox(const VRect &bbox) const
+{
+ mBboxDirty = false;
+ mBbox = bbox;
+}
+
void VRle::VRleData::reset()
{
mSpans.clear();
void *userData);
bool empty() const;
VRect boundingRect() const;
+ void setBoundingRect(const VRect &bbox);
void addSpan(const VRle::Span *span, int count);
void reset();
void addSpan(const VRle::Span *span, int count);
void updateBbox() const;
VRect bbox() const;
+ void setBbox(const VRect &bbox) const;
void reset();
void translate(const VPoint &p);
void operator*=(int alpha);
return d->bbox();
}
+inline void VRle::setBoundingRect(const VRect & bbox)
+{
+ d->setBbox(bbox);
+}
+
inline void VRle::invert()
{
d.write().invert();