summaryrefslogtreecommitdiff
path: root/xfa/fxfa/parser/cxfa_box.cpp
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2018-01-17 18:40:41 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-01-17 18:40:41 +0000
commitaca769671c706607ff29882c46bac77baa449acb (patch)
tree8c312c5073e2b5c7759d6c3467ee985b32bb58c0 /xfa/fxfa/parser/cxfa_box.cpp
parentb73a96938d0fc932a9d498359c98f4cf6ef34160 (diff)
downloadpdfium-aca769671c706607ff29882c46bac77baa449acb.tar.xz
Move rectangle drawing code to CXFA_Rectangle
This CL moves code related to drawing rectangles to the CXFA_Rectangle class. This also turns CXFA_Border into a CXFA_Rectangle to share the drawing code. Change-Id: I91e2e73b33ecbcda477cf953cf7609310a01fcd4 Reviewed-on: https://pdfium-review.googlesource.com/23110 Reviewed-by: Ryan Harrison <rharrison@chromium.org> Commit-Queue: Ryan Harrison <rharrison@chromium.org> Commit-Queue: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'xfa/fxfa/parser/cxfa_box.cpp')
-rw-r--r--xfa/fxfa/parser/cxfa_box.cpp424
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,