1
0
Fork 0

Remote-canvas: fix clip parsing + handling.

This commit is contained in:
James Turner 2016-12-22 16:59:48 +00:00
parent 0e57001cab
commit 980be9f479
2 changed files with 65 additions and 25 deletions

View file

@ -64,26 +64,24 @@ void FGCanvasElement::paint(FGCanvasPaintContext *context) const
QPainter* p = context->painter(); QPainter* p = context->painter();
if (_clipDirty) { if (_clipDirty) {
// re-calculate clip parseCSSClip(_propertyRoot->value("clip", QVariant()).toByteArray());
QVariant clipSpec = _propertyRoot->value("clip", QVariant());
if (clipSpec.isNull()) {
_hasClip = false;
} else {
// https://www.w3.org/wiki/CSS/Properties/clip for the stupid order here
QStringList clipRectDesc = clipSpec.toString().split(',');
int top = clipRectDesc.at(0).toInt();
int right = clipRectDesc.at(1).toInt();
int bottom = clipRectDesc.at(2).toInt();
int left = clipRectDesc.at(3).toInt();
_clipRect = QRectF(left, top, right - left, bottom - top);
_hasClip = true;
}
_clipDirty = false; _clipDirty = false;
} }
p->save(); p->save();
if (_hasClip) {
#if 0
p->save();
p->setPen(Qt::yellow);
p->setBrush(QBrush(Qt::yellow, Qt::DiagCrossPattern));
p->drawRect(_clipRect);
p->restore();
#endif
context->painter()->setClipRect(_clipRect);
context->painter()->setClipping(true);
}
p->setTransform(combinedTransform(), true /* combine */); p->setTransform(combinedTransform(), true /* combine */);
if (_styleDirty) { if (_styleDirty) {
@ -97,16 +95,7 @@ void FGCanvasElement::paint(FGCanvasPaintContext *context) const
p->setBrush(_fillColor); p->setBrush(_fillColor);
} }
if (_hasClip) {
p->save();
p->setPen(Qt::yellow);
p->setBrush(QBrush(Qt::yellow, Qt::DiagCrossPattern));
p->drawRect(_clipRect);
p->restore();
// context->painter()->setClipRect(_clipRect);
// context->painter()->setClipping(true);
}
doPaint(context); doPaint(context);
@ -251,6 +240,24 @@ void FGCanvasElement::markClipDirty()
_clipDirty = true; _clipDirty = true;
} }
float FGCanvasElement::parseCSSValue(QByteArray value) const
{
value = value.trimmed();
// deal with %, px suffixes
if (value.indexOf('%') >= 0) {
qWarning() << Q_FUNC_INFO << "extend parsing to deal with:" << value;
}
if (value.endsWith("px")) {
value.truncate(value.length() - 2);
}
bool ok = false;
float v = value.toFloat(&ok);
if (!ok) {
qWarning() << "failed to parse:" << value;
}
return v;
}
QColor FGCanvasElement::parseColorValue(QVariant value) const QColor FGCanvasElement::parseColorValue(QVariant value) const
{ {
QString colorString = value.toString(); QString colorString = value.toString();
@ -347,3 +354,33 @@ void FGCanvasElement::onVisibleChanged(QVariant value)
{ {
_visible = value.toBool(); _visible = value.toBool();
} }
void FGCanvasElement::parseCSSClip(QByteArray value) const
{
if (value.isEmpty()) {
_hasClip = false;
return;
}
// https://www.w3.org/wiki/CSS/Properties/clip for the stupid order here
if (value.startsWith("rect(")) {
int closingParen = value.indexOf(')');
value = value.mid(5, closingParen - 5); // trim front portion
}
QByteArrayList clipRectDesc = value.split(',');
const int parts = clipRectDesc.size();
if (parts != 4) {
qWarning() << "implement parsing for non-standard clip" << value;
return;
}
const float top = parseCSSValue(clipRectDesc.at(0));
const float right = parseCSSValue(clipRectDesc.at(1));
const float bottom = parseCSSValue(clipRectDesc.at(2));
const float left = parseCSSValue(clipRectDesc.at(3));
_clipRect = QRectF(left, top, right - left, bottom - top);
qDebug() << "final clip rect:" << _clipRect << "from" << value;
_hasClip = true;
}

View file

@ -77,6 +77,9 @@ private:
mutable bool _clipDirty = true; mutable bool _clipDirty = true;
mutable bool _hasClip = false; mutable bool _hasClip = false;
mutable QRectF _clipRect; mutable QRectF _clipRect;
void parseCSSClip(QByteArray value) const;
float parseCSSValue(QByteArray value) const;
}; };
using FGCanvasElementVec = std::vector<FGCanvasElement*>; using FGCanvasElementVec = std::vector<FGCanvasElement*>;