diff options
Diffstat (limited to 'xfa/fxfa/parser/cxfa_box.cpp')
-rw-r--r-- | xfa/fxfa/parser/cxfa_box.cpp | 424 |
1 files changed, 9 insertions, 415 deletions
diff --git a/xfa/fxfa/parser/cxfa_box.cpp b/xfa/fxfa/parser/cxfa_box.cpp index a62ce01146..01e51b313b 100644 --- a/xfa/fxfa/parser/cxfa_box.cpp +++ b/xfa/fxfa/parser/cxfa_box.cpp @@ -15,6 +15,7 @@ #include "xfa/fxfa/parser/cxfa_margin.h" #include "xfa/fxfa/parser/cxfa_measurement.h" #include "xfa/fxfa/parser/cxfa_node.h" +#include "xfa/fxfa/parser/cxfa_rectangle.h" #include "xfa/fxgraphics/cxfa_gepath.h" #include "xfa/fxgraphics/cxfa_gepattern.h" #include "xfa/fxgraphics/cxfa_geshading.h" @@ -76,176 +77,6 @@ void XFA_BOX_GetPath_Arc(CXFA_Box* box, -sweepAngle.value_or(360) * FX_PI / 180.0f); } -void XFA_BOX_GetPath(const std::vector<CXFA_Stroke*>& strokes, - CFX_RectF rtWidget, - CXFA_GEPath& path, - int32_t nIndex, - bool bStart, - bool bCorner) { - ASSERT(nIndex >= 0 && nIndex < 8); - - int32_t n = (nIndex & 1) ? nIndex - 1 : nIndex; - auto* corner1 = static_cast<CXFA_Corner*>(strokes[n]); - auto* corner2 = static_cast<CXFA_Corner*>(strokes[(n + 2) % 8]); - float fRadius1 = bCorner ? corner1->GetRadius() : 0.0f; - float fRadius2 = bCorner ? corner2->GetRadius() : 0.0f; - bool bInverted = corner1->IsInverted(); - float offsetY = 0.0f; - float offsetX = 0.0f; - bool bRound = corner1->GetJoinType() == XFA_AttributeEnum::Round; - float halfAfter = 0.0f; - float halfBefore = 0.0f; - - CXFA_Stroke* stroke = strokes[nIndex]; - if (stroke->IsCorner()) { - CXFA_Stroke* strokeBefore = strokes[(nIndex + 1 * 8 - 1) % 8]; - CXFA_Stroke* strokeAfter = strokes[nIndex + 1]; - if (stroke->IsInverted()) { - if (!stroke->SameStyles(strokeBefore, 0)) - halfBefore = strokeBefore->GetThickness() / 2; - if (!stroke->SameStyles(strokeAfter, 0)) - halfAfter = strokeAfter->GetThickness() / 2; - } - } else { - CXFA_Stroke* strokeBefore = strokes[(nIndex + 8 - 2) % 8]; - CXFA_Stroke* strokeAfter = strokes[(nIndex + 2) % 8]; - if (!bRound && !bInverted) { - halfBefore = strokeBefore->GetThickness() / 2; - halfAfter = strokeAfter->GetThickness() / 2; - } - } - - float offsetEX = 0.0f; - float offsetEY = 0.0f; - 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 cpStart; - CFX_PointF cp1; - CFX_PointF cp2; - if (bRound) { - sy = FX_PI / 2; - } - switch (nIndex) { - case 0: - case 1: - cp1 = rtWidget.TopLeft(); - cp2 = rtWidget.TopRight(); - if (nIndex == 0) { - cpStart.x = cp1.x - halfBefore; - cpStart.y = cp1.y + fRadius1, offsetY = -halfAfter; - } else { - cpStart.x = cp1.x + fRadius1 - halfBefore, cpStart.y = cp1.y, - offsetEX = halfAfter; - } - 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: - case 3: - cp1 = rtWidget.TopRight(); - cp2 = rtWidget.BottomRight(); - if (nIndex == 2) { - cpStart.x = cp1.x - fRadius1, cpStart.y = cp1.y - halfBefore, - offsetX = halfAfter; - } else { - cpStart.x = cp1.x, cpStart.y = cp1.y + fRadius1 - halfBefore, - offsetEY = halfAfter; - } - 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: - case 5: - cp1 = rtWidget.BottomRight(); - cp2 = rtWidget.BottomLeft(); - if (nIndex == 4) { - cpStart.x = cp1.x + halfBefore, cpStart.y = cp1.y - fRadius1, - offsetY = halfAfter; - } else { - cpStart.x = cp1.x - fRadius1 + halfBefore, cpStart.y = cp1.y, - offsetEX = -halfAfter; - } - 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: - case 7: - cp1 = rtWidget.BottomLeft(); - cp2 = rtWidget.TopLeft(); - if (nIndex == 6) { - cpStart.x = cp1.x + fRadius1, cpStart.y = cp1.y + halfBefore, - offsetX = -halfAfter; - } else { - cpStart.x = cp1.x, cpStart.y = cp1.y - fRadius1 + halfBefore, - offsetEY = -halfAfter; - } - vx = 1; - vy = -1; - nx = 0; - ny = 1; - if (bRound) { - sx = bInverted ? 0 : FX_PI / 2; - } else { - sx = 0; - sy = -1; - } - break; - } - if (bStart) { - path.MoveTo(cpStart); - } - if (nIndex & 1) { - path.LineTo(CFX_PointF(cp2.x + fRadius2 * nx + offsetEX, - cp2.y + fRadius2 * ny + offsetEY)); - return; - } - if (bRound) { - if (fRadius1 < 0) - sx -= FX_PI; - if (bInverted) - sy *= -1; - - CFX_RectF rtRadius(cp1.x + offsetX * 2, cp1.y + offsetY * 2, - fRadius1 * 2 * vx - offsetX * 2, - fRadius1 * 2 * vy - offsetY * 2); - rtRadius.Normalize(); - if (bInverted) - rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy); - - path.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; - } - path.LineTo(cp); - path.LineTo(CFX_PointF(cp1.x + fRadius1 * sx + offsetX, - cp1.y + fRadius1 * sy + offsetY)); - } -} - void XFA_BOX_GetFillPath(CXFA_Box* box, const std::vector<CXFA_Stroke*>& strokes, CFX_RectF rtWidget, @@ -483,250 +314,6 @@ void XFA_BOX_StrokeArc(CXFA_Box* box, pGS->RestoreGraphState(); } -void XFA_Draw3DRect(CXFA_Graphics* pGraphic, - const CFX_RectF& rt, - float fLineWidth, - const CFX_Matrix& matrix, - FX_ARGB argbTopLeft, - FX_ARGB argbBottomRight) { - float fBottom = rt.bottom(); - float fRight = rt.right(); - CXFA_GEPath pathLT; - pathLT.MoveTo(CFX_PointF(rt.left, fBottom)); - pathLT.LineTo(CFX_PointF(rt.left, rt.top)); - pathLT.LineTo(CFX_PointF(fRight, rt.top)); - pathLT.LineTo(CFX_PointF(fRight - fLineWidth, rt.top + fLineWidth)); - pathLT.LineTo(CFX_PointF(rt.left + fLineWidth, rt.top + fLineWidth)); - pathLT.LineTo(CFX_PointF(rt.left + fLineWidth, fBottom - fLineWidth)); - pathLT.LineTo(CFX_PointF(rt.left, fBottom)); - pGraphic->SetFillColor(CXFA_GEColor(argbTopLeft)); - pGraphic->FillPath(&pathLT, FXFILL_WINDING, &matrix); - - CXFA_GEPath pathRB; - pathRB.MoveTo(CFX_PointF(fRight, rt.top)); - pathRB.LineTo(CFX_PointF(fRight, fBottom)); - pathRB.LineTo(CFX_PointF(rt.left, fBottom)); - pathRB.LineTo(CFX_PointF(rt.left + fLineWidth, fBottom - fLineWidth)); - pathRB.LineTo(CFX_PointF(fRight - fLineWidth, fBottom - fLineWidth)); - pathRB.LineTo(CFX_PointF(fRight - fLineWidth, rt.top + fLineWidth)); - pathRB.LineTo(CFX_PointF(fRight, rt.top)); - pGraphic->SetFillColor(CXFA_GEColor(argbBottomRight)); - pGraphic->FillPath(&pathRB, FXFILL_WINDING, &matrix); -} - -void XFA_BOX_Stroke_3DRect_Lowered(CXFA_Graphics* pGS, - CFX_RectF rt, - float fThickness, - const CFX_Matrix& matrix) { - float fHalfWidth = fThickness / 2.0f; - CFX_RectF rtInner(rt); - rtInner.Deflate(fHalfWidth, fHalfWidth); - - CXFA_GEPath path; - path.AddRectangle(rt.left, rt.top, rt.width, rt.height); - path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height); - pGS->SetFillColor(CXFA_GEColor(0xFF000000)); - pGS->FillPath(&path, FXFILL_ALTERNATE, &matrix); - XFA_Draw3DRect(pGS, rtInner, fHalfWidth, matrix, 0xFF808080, 0xFFC0C0C0); -} - -void XFA_BOX_Stroke_3DRect_Raised(CXFA_Graphics* pGS, - CFX_RectF rt, - float fThickness, - const CFX_Matrix& matrix) { - float fHalfWidth = fThickness / 2.0f; - CFX_RectF rtInner(rt); - rtInner.Deflate(fHalfWidth, fHalfWidth); - - CXFA_GEPath path; - path.AddRectangle(rt.left, rt.top, rt.width, rt.height); - path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height); - pGS->SetFillColor(CXFA_GEColor(0xFF000000)); - pGS->FillPath(&path, FXFILL_ALTERNATE, &matrix); - XFA_Draw3DRect(pGS, rtInner, fHalfWidth, matrix, 0xFFFFFFFF, 0xFF808080); -} - -void XFA_BOX_Stroke_3DRect_Etched(CXFA_Graphics* pGS, - CFX_RectF rt, - float fThickness, - const CFX_Matrix& matrix) { - float fHalfWidth = fThickness / 2.0f; - XFA_Draw3DRect(pGS, rt, fThickness, matrix, 0xFF808080, 0xFFFFFFFF); - CFX_RectF rtInner(rt); - rtInner.Deflate(fHalfWidth, fHalfWidth); - XFA_Draw3DRect(pGS, rtInner, fHalfWidth, matrix, 0xFFFFFFFF, 0xFF808080); -} - -void XFA_BOX_Stroke_3DRect_Embossed(CXFA_Graphics* pGS, - CFX_RectF rt, - float fThickness, - const CFX_Matrix& matrix) { - float fHalfWidth = fThickness / 2.0f; - XFA_Draw3DRect(pGS, rt, fThickness, matrix, 0xFF808080, 0xFF000000); - CFX_RectF rtInner(rt); - rtInner.Deflate(fHalfWidth, fHalfWidth); - XFA_Draw3DRect(pGS, rtInner, fHalfWidth, matrix, 0xFF000000, 0xFF808080); -} - -void XFA_BOX_Stroke_Rect(CXFA_Box* box, - const std::vector<CXFA_Stroke*>& strokes, - CXFA_Graphics* pGS, - CFX_RectF rtWidget, - const CFX_Matrix& matrix) { - bool bVisible; - float fThickness; - XFA_AttributeEnum i3DType; - std::tie(i3DType, bVisible, fThickness) = box->Get3DStyle(); - if (i3DType != XFA_AttributeEnum::Unknown) { - if (!bVisible || fThickness < 0.001f) { - return; - } - switch (i3DType) { - case XFA_AttributeEnum::Lowered: - XFA_BOX_Stroke_3DRect_Lowered(pGS, rtWidget, fThickness, matrix); - break; - case XFA_AttributeEnum::Raised: - XFA_BOX_Stroke_3DRect_Raised(pGS, rtWidget, fThickness, matrix); - break; - case XFA_AttributeEnum::Etched: - XFA_BOX_Stroke_3DRect_Etched(pGS, rtWidget, fThickness, matrix); - break; - case XFA_AttributeEnum::Embossed: - XFA_BOX_Stroke_3DRect_Embossed(pGS, rtWidget, fThickness, matrix); - break; - default: - NOTREACHED(); - break; - } - return; - } - bool bClose = false; - 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]; - bClose = true; - 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; - } - } - bool bStart = true; - CXFA_GEPath path; - for (int32_t i = 0; i < 8; i++) { - CXFA_Stroke* stroke = strokes[i]; - if ((i % 1) == 0 && stroke->GetRadius() < 0) { - bool bEmpty = path.IsEmpty(); - if (!bEmpty) { - if (stroke) - stroke->Stroke(&path, pGS, matrix); - path.Clear(); - } - bStart = true; - continue; - } - XFA_BOX_GetPath(strokes, rtWidget, path, i, bStart, !bSameStyles); - - bStart = !stroke->SameStyles(strokes[(i + 1) % 8], 0); - if (bStart) { - if (stroke) - stroke->Stroke(&path, pGS, matrix); - path.Clear(); - } - } - bool bEmpty = path.IsEmpty(); - if (!bEmpty) { - if (bClose) { - path.Close(); - } - if (strokes[7]) - strokes[7]->Stroke(&path, pGS, matrix); - } -} - -void XFA_BOX_Stroke(CXFA_Box* box, - const std::vector<CXFA_Stroke*>& strokes, - CXFA_Graphics* pGS, - CFX_RectF rtWidget, - const CFX_Matrix& matrix, - bool forceRound) { - if (box->IsArc() || forceRound) { - XFA_BOX_StrokeArc(box, pGS, rtWidget, matrix, forceRound); - return; - } - - bool bVisible = false; - for (int32_t j = 0; j < 4; j++) { - if (strokes[j * 2 + 1]->IsVisible()) { - bVisible = true; - break; - } - } - if (!bVisible) - return; - - for (int32_t i = 1; i < 8; i += 2) { - float fThickness = std::fmax(0.0, strokes[i]->GetThickness()); - float fHalf = fThickness / 2; - XFA_AttributeEnum iHand = box->GetHand(); - switch (i) { - case 1: - if (iHand == XFA_AttributeEnum::Left) { - rtWidget.top -= fHalf; - rtWidget.height += fHalf; - } else if (iHand == XFA_AttributeEnum::Right) { - rtWidget.top += fHalf; - rtWidget.height -= fHalf; - } - break; - case 3: - if (iHand == XFA_AttributeEnum::Left) { - rtWidget.width += fHalf; - } else if (iHand == XFA_AttributeEnum::Right) { - rtWidget.width -= fHalf; - } - break; - case 5: - if (iHand == XFA_AttributeEnum::Left) { - rtWidget.height += fHalf; - } else if (iHand == XFA_AttributeEnum::Right) { - rtWidget.height -= fHalf; - } - break; - case 7: - if (iHand == XFA_AttributeEnum::Left) { - rtWidget.left -= fHalf; - rtWidget.width += fHalf; - } else if (iHand == XFA_AttributeEnum::Right) { - rtWidget.left += fHalf; - rtWidget.width -= fHalf; - } - break; - } - } - XFA_BOX_Stroke_Rect(box, strokes, pGS, rtWidget, matrix); -} - } // namespace CXFA_Box::CXFA_Box(CXFA_Document* pDoc, @@ -877,7 +464,14 @@ void CXFA_Box::Draw(CXFA_Graphics* pGS, strokes = GetStrokes(); DrawFill(strokes, pGS, rtWidget, matrix, forceRound); - XFA_BOX_Stroke(this, strokes, pGS, rtWidget, matrix, forceRound); + XFA_Element type = GetElementType(); + if (type == XFA_Element::Arc || forceRound) { + XFA_BOX_StrokeArc(this, pGS, rtWidget, matrix, forceRound); + } else if (type == XFA_Element::Rectangle || type == XFA_Element::Border) { + static_cast<CXFA_Rectangle*>(this)->Draw(strokes, pGS, rtWidget, matrix); + } else { + NOTREACHED(); + } } void CXFA_Box::DrawFill(const std::vector<CXFA_Stroke*>& strokes, |