* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
VRle rle;
for (auto &e : mMasks) {
- auto cur = e.rle();
- if (e.inverted()) cur = VRle::toRle(clipRect) - cur;
+ const auto cur = [&]() {
+ if (e.inverted())
+ return clipRect - e.rle();
+ else
+ return e.rle();
+ }();
switch (e.maskMode()) {
case model::Mask::Mode::Add: {
break;
}
case model::Mask::Mode::Substarct: {
- if (rle.empty() && !clipRect.empty()) rle = VRle::toRle(clipRect);
- rle = rle - cur;
+ if (rle.empty() && !clipRect.empty())
+ rle = clipRect - cur;
+ else
+ rle = rle - cur;
break;
}
case model::Mask::Mode::Intersect: {
- if (rle.empty() && !clipRect.empty()) rle = VRle::toRle(clipRect);
- rle = rle & cur;
+ if (rle.empty() && !clipRect.empty())
+ rle = clipRect & cur;
+ else
+ rle = rle & cur;
break;
}
case model::Mask::Mode::Difference: {
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- * The above copyright notice and this permission notice shall be included in all
+ * The above copyright notice and this permission notice shall be included in
+ all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
span.coverage = 255;
mSpans.push_back(span);
}
- updateBbox();
+ mBbox = rect;
}
void VRle::VRleData::updateBbox() const
}
}
-void VRle::VRleData::invert()
-{
- for (auto &i : mSpans) {
- i.coverage = 255 - i.coverage;
- }
-}
-
void VRle::VRleData::operator*=(uchar alpha)
{
for (auto &i : mSpans) {
result->size = result->alloc - available;
}
-VRle VRle::toRle(const VRect &rect)
-{
- if (rect.empty()) return VRle();
-
- VRle result;
- result.d.write().addRect(rect);
- return result;
-}
-
/*
* this api makes use of thread_local temporary
* buffer to avoid creating intermediate temporary rle buffer
d.write() = Scratch_Object;
}
+VRle operator-(const VRect &rect, const VRle &o)
+{
+ if (rect.empty()) return {};
+
+ Scratch_Object.reset();
+ Scratch_Object.addRect(rect);
+
+ VRle result;
+ result.d.write().opSubstract(Scratch_Object, o.d.read());
+
+ return result;
+}
+
+VRle operator&(const VRect &rect, const VRle &o)
+{
+ if (rect.empty() || o.empty()) return {};
+
+ Scratch_Object.reset();
+ Scratch_Object.addRect(rect);
+
+ VRle result;
+ result.d.write().opIntersect(Scratch_Object, o.d.read());
+
+ return result;
+}
+
V_END_NAMESPACE
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ushort len{0};
uchar coverage{0};
};
- using VRleSpanCb = void (*)(size_t count, const VRle::Span *spans,
- void *userData);
+ using VRleSpanCb = void (*)(size_t count, const VRle::Span *spans,
+ void *userData);
bool empty() const;
VRect boundingRect() const;
- void setBoundingRect(const VRect &bbox);
+ void setBoundingRect(const VRect &bbox);
void addSpan(const VRle::Span *span, size_t count);
void reset();
void translate(const VPoint &p);
- void invert();
void operator*=(uchar alpha);
VRle operator+(const VRle &o) const;
VRle operator^(const VRle &o) const;
- static VRle toRle(const VRect &rect);
+ friend VRle operator-(const VRect &rect, const VRle &o);
+ friend VRle operator&(const VRect &rect, const VRle &o);
- bool unique() const {return d.unique();}
- size_t refCount() const { return d.refCount();}
- void clone(const VRle &o);
+ bool unique() const { return d.unique(); }
+ size_t refCount() const { return d.refCount(); }
+ void clone(const VRle &o);
public:
struct VRleData {
- enum class OpCode {
- Add,
- Xor
- };
+ enum class OpCode { Add, Xor };
bool empty() const { return mSpans.empty(); }
void addSpan(const VRle::Span *span, size_t count);
void updateBbox() const;
VRect bbox() const;
- void setBbox(const VRect &bbox) const;
+ void setBbox(const VRect &bbox) const;
void reset();
void translate(const VPoint &p);
void operator*=(uchar alpha);
- void invert();
void opIntersect(const VRect &, VRle::VRleSpanCb, void *) const;
- void opGeneric(const VRle::VRleData &, const VRle::VRleData &, OpCode code);
+ void opGeneric(const VRle::VRleData &, const VRle::VRleData &,
+ OpCode code);
void opSubstract(const VRle::VRleData &, const VRle::VRleData &);
void opIntersect(const VRle::VRleData &, const VRle::VRleData &);
void addRect(const VRect &rect);
void clone(const VRle::VRleData &);
+
std::vector<VRle::Span> mSpans;
VPoint mOffset;
mutable VRect mBbox;
mutable bool mBboxDirty = true;
};
+
private:
friend void opIntersectHelper(const VRle::VRleData &obj1,
const VRle::VRleData &obj2,
VRle::VRleSpanCb cb, void *userData);
+
vcow_ptr<VRleData> d;
};
return d->bbox();
}
-inline void VRle::setBoundingRect(const VRect & bbox)
+inline void VRle::setBoundingRect(const VRect &bbox)
{
d->setBbox(bbox);
}
-inline void VRle::invert()
-{
- d.write().invert();
-}
-
inline void VRle::operator*=(uchar alpha)
{
d.write() *= alpha;