7#include "xfa/fxfa/parser/cxfa_box.h"
14#include "fxjs/xfa/cjx_object.h"
15#include "third_party/base/notreached.h"
16#include "third_party/base/numerics/safe_conversions.h"
17#include "xfa/fgas/graphics/cfgas_gegraphics.h"
18#include "xfa/fgas/graphics/cfgas_gepath.h"
19#include "xfa/fgas/graphics/cfgas_gepattern.h"
20#include "xfa/fgas/graphics/cfgas_geshading.h"
21#include "xfa/fxfa/parser/cxfa_corner.h"
22#include "xfa/fxfa/parser/cxfa_edge.h"
23#include "xfa/fxfa/parser/cxfa_fill.h"
24#include "xfa/fxfa/parser/cxfa_margin.h"
25#include "xfa/fxfa/parser/cxfa_measurement.h"
26#include "xfa/fxfa/parser/cxfa_node.h"
27#include "xfa/fxfa/parser/cxfa_rectangle.h"
32 const std::vector<CXFA_Stroke*>& strokes) {
37 for (size_t i = 1; i < strokes.size(); i++) {
53 return {iType, stroke};
94 return CountChildren(XFA_Element::Edge,
false);
99 return JSObject()->GetOrCreateProperty<CXFA_Edge>(
100 pdfium::base::checked_cast<int32_t>(nIndex),
XFA_Element::Edge);
102 return JSObject()->GetProperty<CXFA_Edge>(
103 pdfium::base::checked_cast<int32_t>(nIndex),
XFA_Element::Edge);
107 return GetStrokesInternal(
false);
114absl::optional<int32_t>
CXFA_Box::GetStartAngle() {
115 return JSObject()->TryInteger(
XFA_Attribute::StartAngle,
false);
118absl::optional<int32_t>
CXFA_Box::GetSweepAngle() {
119 return JSObject()->TryInteger(
XFA_Attribute::SweepAngle,
false);
123 return JSObject()->GetOrCreateProperty<CXFA_Fill>(0,
XFA_Element::Fill);
130 std::vector<CXFA_Stroke*> strokes = GetStrokesInternal(
true);
134 std::tie(iType, stroke) = Style3D(strokes);
141std::vector<CXFA_Stroke*>
CXFA_Box::GetStrokesInternal(
bool bNull) {
142 std::vector<CXFA_Stroke*> strokes;
145 for (int32_t i = 0, j = 0; i < 4; i++) {
149 JSObject()->GetOrCreateProperty<CXFA_Corner>(i,
XFA_Element::Corner);
151 corner = JSObject()->GetProperty<CXFA_Corner>(i,
XFA_Element::Corner);
156 if (corner || i == 0) {
159 if (i == 1 || i == 2)
160 strokes[j] = strokes[0];
162 strokes[j] = strokes[2];
168 edge = JSObject()->GetOrCreateProperty<CXFA_Edge>(i,
XFA_Element::Edge);
170 edge = JSObject()->GetProperty<CXFA_Edge>(i,
XFA_Element::Edge);
174 if (edge || i == 0) {
177 if (i == 1 || i == 2)
178 strokes[j] = strokes[1];
180 strokes[j] = strokes[3];
199 std::vector<CXFA_Stroke*> strokes;
200 if (!forceRound && eType != XFA_Element::Arc)
201 strokes = GetStrokes();
203 DrawFill(strokes, pGS, rtWidget, matrix, forceRound);
206 StrokeArcOrRounded(pGS, rtWidget, matrix, forceRound);
208 ToRectangle(
this)->Draw(strokes, pGS, rtWidget, matrix);
210 NOTREACHED_NORETURN();
214void CXFA_Box::DrawFill(
const std::vector<CXFA_Stroke*>& strokes,
219 CXFA_Fill* fill = JSObject()->GetProperty<CXFA_Fill>(0,
XFA_Element::Fill);
223 CFGAS_GEPath fillPath;
227 CXFA_Edge* edge = GetEdgeIfExists(0);
229 float fHalf = fThickness / 2;
236 GetPathArcOrRounded(rtWidget, forceRound, &fillPath);
238 ToRectangle(
this)->GetFillPath(strokes, rtWidget, &fillPath);
240 NOTREACHED_NORETURN();
248 CFGAS_GEPath* fillPath) {
249 float a = rtDraw
.width / 2.0f;
250 float b = rtDraw
.height / 2.0f;
251 if (IsCircular() || forceRound)
252 a = b =
std::min(a, b);
254 CFX_PointF center = rtDraw.Center();
255 rtDraw
.left = center.x - a;
256 rtDraw
.top = center.y - b;
259 absl::optional<int32_t> startAngle = GetStartAngle();
260 absl::optional<int32_t> sweepAngle = GetSweepAngle();
261 if (!startAngle.has_value() && !sweepAngle.has_value()) {
266 fillPath->AddArc(rtDraw.TopLeft(), rtDraw.Size(),
267 -startAngle.value_or(0) *
FXSYS_PI / 180.0f,
268 -sweepAngle.value_or(360) *
FXSYS_PI / 180.0f);
275 CXFA_Edge* edge = GetEdgeIfExists(0);
282 std::tie(i3DType, bVisible, fThickness) = Get3DStyle();
283 bool lowered3d =
false;
285 if (bVisible && fThickness >= 0.001f)
300 if (!forceRound || !lowered3d) {
304 CFGAS_GEPath arcPath;
305 GetPathArcOrRounded(rtWidget, forceRound, &arcPath);
313 float a = rtWidget
.width / 2.0f;
314 float b = rtWidget
.height / 2.0f;
320 CFX_PointF center = rtWidget.Center();
321 rtWidget
.left = center.x - a;
322 rtWidget
.top = center.y - b;
326 CFGAS_GEPath arcPath;
CFGAS_GEColor(const FX_ARGB argb)
StateRestorer(CFGAS_GEGraphics *graphics)
void SetLineWidth(float lineWidth)
void SetStrokeColor(const CFGAS_GEColor &color)
void StrokePath(const CFGAS_GEPath &path, const CFX_Matrix &matrix)
void AddEllipse(const CFX_RectF &rect)
void AddArc(const CFX_PointF &pos, const CFX_SizeF &size, float startAngle, float sweepAngle)
void Inflate(float x, float y)
void Deflate(float x, float y)
std::tuple< XFA_AttributeValue, bool, float > Get3DStyle()
std::vector< CXFA_Stroke * > GetStrokes()
XFA_AttributeValue GetHand()
CXFA_Edge * GetEdgeIfExists(size_t nIndex)
XFA_AttributeValue GetPresence()
CXFA_Fill * GetOrCreateFillIfPossible()
void Draw(CFGAS_GEGraphics *pGS, const CFX_RectF &rtWidget, const CFX_Matrix &matrix, bool forceRound)
CXFA_Box(CXFA_Document *pDoc, XFA_PacketType ePacket, Mask< XFA_XDPPACKET > validPackets, XFA_ObjectType oType, XFA_Element eType, pdfium::span< const PropertyData > properties, pdfium::span< const AttributeData > attributes, CJX_Object *js_node)
void Draw(CFGAS_GEGraphics *pGS, const CFGAS_GEPath &fillPath, const CFX_RectF &rtWidget, const CFX_Matrix &matrix)
XFA_Element GetElementType() const
void Stroke(CFGAS_GEGraphics *pGS, const CFGAS_GEPath &pPath, const CFX_Matrix &matrix)
float GetThickness() const
XFA_AttributeValue GetStrokeType()