Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
69fa7457
Commit
69fa7457
authored
Jul 11, 2007
by
Evan Stade
Committed by
Alexandre Julliard
Jul 12, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdiplus: Added GdipAddPathArc.
parent
4a8a1b42
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
143 additions
and
1 deletion
+143
-1
gdiplus.c
dlls/gdiplus/gdiplus.c
+107
-0
gdiplus.spec
dlls/gdiplus/gdiplus.spec
+1
-1
gdiplus_private.h
dlls/gdiplus/gdiplus_private.h
+3
-0
graphicspath.c
dlls/gdiplus/graphicspath.c
+31
-0
gdiplusflat.h
include/gdiplusflat.h
+1
-0
No files found.
dlls/gdiplus/gdiplus.c
View file @
69fa7457
...
...
@@ -17,12 +17,14 @@
*/
#include <stdarg.h>
#include <math.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "gdiplus.h"
#include "gdiplus_private.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
gdiplus
);
...
...
@@ -92,6 +94,111 @@ void WINGDIPAPI GdipFree(void* ptr)
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
}
/* Calculates the bezier points needed to fill in the arc portion starting at
* angle start and ending at end. These two angles should be no more than 90
* degrees from each other. x1, y1, x2, y2 describes the bounding box (upper
* left and width and height). Angles must be in radians. write_first indicates
* that the first bezier point should be written out (usually this is false).
* pt is the array of GpPointFs that gets written to.
**/
static
void
add_arc_part
(
GpPointF
*
pt
,
REAL
x1
,
REAL
y1
,
REAL
x2
,
REAL
y2
,
REAL
start
,
REAL
end
,
BOOL
write_first
)
{
REAL
center_x
,
center_y
,
rad_x
,
rad_y
,
cos_start
,
cos_end
,
sin_start
,
sin_end
,
a
,
half
;
INT
i
;
rad_x
=
x2
/
2
.
0
;
rad_y
=
y2
/
2
.
0
;
center_x
=
x1
+
rad_x
;
center_y
=
y1
+
rad_y
;
cos_start
=
cos
(
start
);
cos_end
=
cos
(
end
);
sin_start
=
sin
(
start
);
sin_end
=
sin
(
end
);
half
=
(
end
-
start
)
/
2
.
0
;
a
=
4
.
0
/
3
.
0
*
(
1
-
cos
(
half
))
/
sin
(
half
);
if
(
write_first
){
pt
[
0
].
X
=
cos_start
;
pt
[
0
].
Y
=
sin_start
;
}
pt
[
1
].
X
=
cos_start
-
a
*
sin_start
;
pt
[
1
].
Y
=
sin_start
+
a
*
cos_start
;
pt
[
3
].
X
=
cos_end
;
pt
[
3
].
Y
=
sin_end
;
pt
[
2
].
X
=
cos_end
+
a
*
sin_end
;
pt
[
2
].
Y
=
sin_end
-
a
*
cos_end
;
/* expand the points back from the unit circle to the ellipse */
for
(
i
=
(
write_first
?
0
:
1
);
i
<
4
;
i
++
){
pt
[
i
].
X
=
pt
[
i
].
X
*
rad_x
+
center_x
;
pt
[
i
].
Y
=
pt
[
i
].
Y
*
rad_y
+
center_y
;
}
}
/* We plot the curve as if it is on a circle then stretch the points. This
* adjusts the angles so that when we stretch the points they will end in the
* right place. This is only complicated because atan and atan2 do not behave
* conveniently. */
static
void
unstretch_angle
(
REAL
*
angle
,
REAL
rad_x
,
REAL
rad_y
)
{
REAL
stretched
;
INT
revs_off
;
*
angle
=
deg2rad
(
*
angle
);
if
(
cos
(
*
angle
)
==
0
||
sin
(
*
angle
)
==
0
)
return
;
stretched
=
atan2
(
sin
(
*
angle
)
/
rad_y
,
cos
(
*
angle
)
/
rad_x
);
revs_off
=
roundr
(
*
angle
/
(
2
.
0
*
M_PI
))
-
roundr
(
stretched
/
(
2
.
0
*
M_PI
));
stretched
+=
((
REAL
)
revs_off
)
*
M_PI
*
2
.
0
;
*
angle
=
stretched
;
}
/* Stores the bezier points that correspond to the arc in points. If points is
* null, just return the number of points needed to represent the arc. */
INT
arc2polybezier
(
GpPointF
*
points
,
REAL
x1
,
REAL
y1
,
REAL
x2
,
REAL
y2
,
REAL
startAngle
,
REAL
sweepAngle
)
{
INT
i
,
count
;
REAL
end_angle
,
start_angle
,
endAngle
;
endAngle
=
startAngle
+
sweepAngle
;
unstretch_angle
(
&
startAngle
,
x2
/
2
.
0
,
y2
/
2
.
0
);
unstretch_angle
(
&
endAngle
,
x2
/
2
.
0
,
y2
/
2
.
0
);
count
=
ceilf
(
fabs
(
endAngle
-
startAngle
)
/
M_PI_2
)
*
3
+
1
;
/* don't make more than a full circle */
count
=
min
(
MAX_ARC_PTS
,
count
);
if
(
count
==
1
)
return
0
;
if
(
!
points
)
return
count
;
/* start_angle and end_angle are the iterative variables */
start_angle
=
startAngle
;
for
(
i
=
0
;
i
<
count
-
1
;
i
+=
3
){
/* check if we've overshot the end angle */
if
(
sweepAngle
>
0
.
0
)
end_angle
=
min
(
start_angle
+
M_PI_2
,
endAngle
);
else
end_angle
=
max
(
start_angle
-
M_PI_2
,
endAngle
);
add_arc_part
(
&
points
[
i
],
x1
,
y1
,
x2
,
y2
,
start_angle
,
end_angle
,
i
==
0
);
start_angle
+=
M_PI_2
*
(
sweepAngle
<
0
.
0
?
-
1
.
0
:
1
.
0
);
}
return
count
;
}
COLORREF
ARGB2COLORREF
(
ARGB
color
)
{
/*
...
...
dlls/gdiplus/gdiplus.spec
View file @
69fa7457
@ st
ub GdipAddPathArc
@ st
dcall GdipAddPathArc(ptr long long long long long long)
@ stub GdipAddPathArcI
@ stub GdipAddPathBezier
@ stub GdipAddPathBezierI
...
...
dlls/gdiplus/gdiplus_private.h
View file @
69fa7457
...
...
@@ -24,8 +24,11 @@
#include "gdiplus.h"
#define GP_DEFAULT_PENSTYLE (PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_MITER)
#define MAX_ARC_PTS (13)
COLORREF
ARGB2COLORREF
(
ARGB
color
);
extern
INT
arc2polybezier
(
GpPointF
*
points
,
REAL
x1
,
REAL
y1
,
REAL
x2
,
REAL
y2
,
REAL
startAngle
,
REAL
sweepAngle
);
static
inline
INT
roundr
(
REAL
x
)
{
...
...
dlls/gdiplus/graphicspath.c
View file @
69fa7457
...
...
@@ -63,6 +63,37 @@ static BOOL lengthen_path(GpPath *path, INT len)
return
TRUE
;
}
GpStatus
WINGDIPAPI
GdipAddPathArc
(
GpPath
*
path
,
REAL
x1
,
REAL
y1
,
REAL
x2
,
REAL
y2
,
REAL
startAngle
,
REAL
sweepAngle
)
{
INT
count
,
old_count
,
i
;
if
(
!
path
)
return
InvalidParameter
;
count
=
arc2polybezier
(
NULL
,
x1
,
y1
,
x2
,
y2
,
startAngle
,
sweepAngle
);
if
(
count
==
0
)
return
Ok
;
if
(
!
lengthen_path
(
path
,
count
))
return
OutOfMemory
;
old_count
=
path
->
pathdata
.
Count
;
arc2polybezier
(
&
path
->
pathdata
.
Points
[
old_count
],
x1
,
y1
,
x2
,
y2
,
startAngle
,
sweepAngle
);
for
(
i
=
0
;
i
<
count
;
i
++
){
path
->
pathdata
.
Types
[
old_count
+
i
]
=
PathPointTypeBezier
;
}
path
->
pathdata
.
Types
[
old_count
]
=
(
path
->
newfigure
?
PathPointTypeStart
:
PathPointTypeLine
);
path
->
newfigure
=
FALSE
;
path
->
pathdata
.
Count
+=
count
;
return
Ok
;
}
GpStatus
WINGDIPAPI
GdipAddPathLine2
(
GpPath
*
path
,
GDIPCONST
GpPointF
*
points
,
INT
count
)
{
...
...
include/gdiplusflat.h
View file @
69fa7457
...
...
@@ -48,6 +48,7 @@ GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB,GpSolidFill**);
GpStatus
WINGDIPAPI
GdipGetBrushType
(
GpBrush
*
,
GpBrushType
*
);
GpStatus
WINGDIPAPI
GdipDeleteBrush
(
GpBrush
*
);
GpStatus
WINGDIPAPI
GdipAddPathArc
(
GpPath
*
,
REAL
,
REAL
,
REAL
,
REAL
,
REAL
,
REAL
);
GpStatus
WINGDIPAPI
GdipAddPathLine2
(
GpPath
*
,
GDIPCONST
GpPointF
*
,
INT
);
GpStatus
WINGDIPAPI
GdipClosePathFigure
(
GpPath
*
);
GpStatus
WINGDIPAPI
GdipClosePathFigures
(
GpPath
*
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment