7#include "xfa/fxfa/parser/cxfa_box.h"
14#include "core/fxcrt/notreached.h"
15#include "core/fxcrt/numerics/safe_conversions.h"
16#include "fxjs/xfa/cjx_object.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};
69 pdfium::span<
const PropertyData> properties,
70 pdfium::span<
const AttributeData> attributes,
94 return CountChildren(XFA_Element::Edge,
false);
99 return JSObject()->GetOrCreateProperty<CXFA_Edge>(
102 return JSObject()->GetProperty<CXFA_Edge>(
107 return GetStrokesInternal(
false);
115 return JSObject()->TryInteger(
XFA_Attribute::StartAngle,
false);
119 return JSObject()->TryInteger(
XFA_Attribute::SweepAngle,
false);
123 return JSObject()->GetOrCreateProperty<CXFA_Fill>(0,
XFA_Element::Fill);
131 std::vector<CXFA_Stroke*> strokes = GetStrokesInternal(
true);
132 auto [iType, stroke] = Style3D(strokes);
133 if (iType == XFA_AttributeValue::Unknown) {
137 return {iType, stroke->IsVisible(), stroke->GetThickness()};
140std::vector<CXFA_Stroke*>
CXFA_Box::GetStrokesInternal(
bool bNull) {
141 std::vector<CXFA_Stroke*> strokes;
144 for (int32_t i = 0, j = 0; i < 4; i++) {
148 JSObject()->GetOrCreateProperty<CXFA_Corner>(i,
XFA_Element::Corner);
150 corner = JSObject()->GetProperty<CXFA_Corner>(i,
XFA_Element::Corner);
155 if (corner || i == 0) {
158 if (i == 1 || i == 2)
159 strokes[j] = strokes[0];
161 strokes[j] = strokes[2];
167 edge = JSObject()->GetOrCreateProperty<CXFA_Edge>(i,
XFA_Element::Edge);
169 edge = JSObject()->GetProperty<CXFA_Edge>(i,
XFA_Element::Edge);
173 if (edge || i == 0) {
176 if (i == 1 || i == 2)
177 strokes[j] = strokes[1];
179 strokes[j] = strokes[3];
198 std::vector<CXFA_Stroke*> strokes;
199 if (!forceRound && eType != XFA_Element::Arc)
200 strokes = GetStrokes();
202 DrawFill(strokes, pGS, rtWidget, matrix, forceRound);
205 StrokeArcOrRounded(pGS, rtWidget, matrix, forceRound);
207 ToRectangle(
this)->Draw(strokes, pGS, rtWidget, matrix);
213void CXFA_Box::DrawFill(
const std::vector<CXFA_Stroke*>& strokes,
218 CXFA_Fill* fill = JSObject()->GetProperty<CXFA_Fill>(0,
XFA_Element::Fill);
222 CFGAS_GEPath fillPath;
226 CXFA_Edge* edge = GetEdgeIfExists(0);
228 float fHalf = fThickness / 2;
235 GetPathArcOrRounded(rtWidget, forceRound, &fillPath);
237 ToRectangle(
this)->GetFillPath(strokes, rtWidget, &fillPath);
247 CFGAS_GEPath* fillPath) {
248 float a = rtDraw
.width / 2.0f;
249 float b = rtDraw
.height / 2.0f;
250 if (IsCircular() || forceRound)
251 a = b =
std::min(a, b);
254 rtDraw
.left = center.x - a;
255 rtDraw
.top = center.y - b;
258 std::optional<int32_t> startAngle = GetStartAngle();
259 std::optional<int32_t> sweepAngle = GetSweepAngle();
260 if (!startAngle.has_value() && !sweepAngle.has_value()) {
266 -startAngle.value_or(0) *
FXSYS_PI / 180.0f
,
267 -sweepAngle.value_or(360) *
FXSYS_PI / 180.0f
);
274 CXFA_Edge* edge = GetEdgeIfExists(0);
278 auto [i3DType, bVisible, fThickness] = Get3DStyle();
279 bool lowered3d =
false;
280 if (i3DType != XFA_AttributeValue::Unknown) {
281 if (bVisible && fThickness >= 0.001f)
296 if (!forceRound || !lowered3d) {
300 CFGAS_GEPath arcPath;
301 GetPathArcOrRounded(rtWidget, forceRound, &arcPath);
309 float a = rtWidget
.width / 2.0f;
310 float b = rtWidget
.height / 2.0f;
317 rtWidget
.left = center.x - a;
318 rtWidget
.top = center.y - b;
322 CFGAS_GEPath arcPath;
CFGAS_GEColor(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()
CFX_PTemplate< float > CFX_PointF
#define NOTREACHED_NORETURN()