summaryrefslogtreecommitdiff
path: root/xfa/fxfa/parser/cxfa_rectangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa/parser/cxfa_rectangle.cpp')
-rw-r--r--xfa/fxfa/parser/cxfa_rectangle.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/xfa/fxfa/parser/cxfa_rectangle.cpp b/xfa/fxfa/parser/cxfa_rectangle.cpp
index 861cf443a7..ac98df0bb7 100644
--- a/xfa/fxfa/parser/cxfa_rectangle.cpp
+++ b/xfa/fxfa/parser/cxfa_rectangle.cpp
@@ -63,6 +63,140 @@ CXFA_Rectangle::CXFA_Rectangle(CXFA_Document* pDoc,
CXFA_Rectangle::~CXFA_Rectangle() {}
+void CXFA_Rectangle::GetFillPath(const std::vector<CXFA_Stroke*>& strokes,
+ const CFX_RectF& rtWidget,
+ CXFA_GEPath* fillPath) {
+ bool bSameStyles = true;
+ CXFA_Stroke* stroke1 = strokes[0];
+ for (int32_t i = 1; i < 8; i++) {
+ CXFA_Stroke* stroke2 = strokes[i];
+ if (!stroke1->SameStyles(stroke2, 0)) {
+ bSameStyles = false;
+ break;
+ }
+ stroke1 = stroke2;
+ }
+
+ if (bSameStyles) {
+ stroke1 = strokes[0];
+ for (int32_t i = 2; i < 8; i += 2) {
+ CXFA_Stroke* stroke2 = strokes[i];
+ if (!stroke1->SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
+ XFA_STROKE_SAMESTYLE_Corner)) {
+ bSameStyles = false;
+ break;
+ }
+ stroke1 = stroke2;
+ }
+ if (bSameStyles) {
+ stroke1 = strokes[0];
+ if (stroke1->IsInverted())
+ bSameStyles = false;
+ if (stroke1->GetJoinType() != XFA_AttributeEnum::Square)
+ bSameStyles = false;
+ }
+ }
+ if (bSameStyles) {
+ fillPath->AddRectangle(rtWidget.left, rtWidget.top, rtWidget.width,
+ rtWidget.height);
+ return;
+ }
+
+ for (int32_t i = 0; i < 8; i += 2) {
+ float sx = 0.0f;
+ float sy = 0.0f;
+ float vx = 1.0f;
+ float vy = 1.0f;
+ float nx = 1.0f;
+ float ny = 1.0f;
+ CFX_PointF cp1, cp2;
+ auto* corner1 = static_cast<CXFA_Corner*>(strokes[i]);
+ auto* corner2 = static_cast<CXFA_Corner*>(strokes[(i + 2) % 8]);
+ float fRadius1 = corner1->GetRadius();
+ float fRadius2 = corner2->GetRadius();
+ bool bInverted = corner1->IsInverted();
+ bool bRound = corner1->GetJoinType() == XFA_AttributeEnum::Round;
+ if (bRound) {
+ sy = FX_PI / 2;
+ }
+ switch (i) {
+ case 0:
+ cp1 = rtWidget.TopLeft();
+ cp2 = rtWidget.TopRight();
+ vx = 1, vy = 1;
+ nx = -1, ny = 0;
+ if (bRound) {
+ sx = bInverted ? FX_PI / 2 : FX_PI;
+ } else {
+ sx = 1, sy = 0;
+ }
+ break;
+ case 2:
+ cp1 = rtWidget.TopRight();
+ cp2 = rtWidget.BottomRight();
+ vx = -1, vy = 1;
+ nx = 0, ny = -1;
+ if (bRound) {
+ sx = bInverted ? FX_PI : FX_PI * 3 / 2;
+ } else {
+ sx = 0, sy = 1;
+ }
+ break;
+ case 4:
+ cp1 = rtWidget.BottomRight();
+ cp2 = rtWidget.BottomLeft();
+ vx = -1, vy = -1;
+ nx = 1, ny = 0;
+ if (bRound) {
+ sx = bInverted ? FX_PI * 3 / 2 : 0;
+ } else {
+ sx = -1, sy = 0;
+ }
+ break;
+ case 6:
+ cp1 = rtWidget.BottomLeft();
+ cp2 = rtWidget.TopLeft();
+ vx = 1, vy = -1;
+ nx = 0, ny = 1;
+ if (bRound) {
+ sx = bInverted ? 0 : FX_PI / 2;
+ } else {
+ sx = 0;
+ sy = -1;
+ }
+ break;
+ }
+ if (i == 0)
+ fillPath->MoveTo(CFX_PointF(cp1.x, cp1.y + fRadius1));
+
+ if (bRound) {
+ if (fRadius1 < 0)
+ sx -= FX_PI;
+ if (bInverted)
+ sy *= -1;
+
+ CFX_RectF rtRadius(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy);
+ rtRadius.Normalize();
+ if (bInverted)
+ rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
+
+ fillPath->ArcTo(rtRadius.TopLeft(), rtRadius.Size(), sx, sy);
+ } else {
+ CFX_PointF cp;
+ if (bInverted) {
+ cp.x = cp1.x + fRadius1 * vx;
+ cp.y = cp1.y + fRadius1 * vy;
+ } else {
+ cp = cp1;
+ }
+ fillPath->LineTo(cp);
+ fillPath->LineTo(
+ CFX_PointF(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy));
+ }
+ fillPath->LineTo(CFX_PointF(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny));
+ }
+}
+
void CXFA_Rectangle::Draw(const std::vector<CXFA_Stroke*>& strokes,
CXFA_Graphics* pGS,
CFX_RectF rtWidget,