Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
2a208bd2
Commit
2a208bd2
authored
Nov 01, 2012
by
Sam Edwards
Committed by
Alexandre Julliard
Nov 05, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
opengl32: Implement wglUseFontOutlines curve smoothing.
parent
9d4fcaf2
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
173 additions
and
49 deletions
+173
-49
wgl.c
dlls/opengl32/wgl.c
+173
-49
No files found.
dlls/opengl32/wgl.c
View file @
2a208bd2
...
...
@@ -1311,6 +1311,74 @@ static void WINAPI tess_callback_end(void)
funcs
->
gl
.
p_glEnd
();
}
typedef
struct
_bezier_vector
{
GLdouble
x
;
GLdouble
y
;
}
bezier_vector
;
static
double
bezier_deviation_squared
(
const
bezier_vector
*
p
)
{
bezier_vector
deviation
;
bezier_vector
vertex
;
bezier_vector
base
;
double
base_length
;
double
dot
;
vertex
.
x
=
(
p
[
0
].
x
+
p
[
1
].
x
*
2
+
p
[
2
].
x
)
/
4
-
p
[
0
].
x
;
vertex
.
y
=
(
p
[
0
].
y
+
p
[
1
].
y
*
2
+
p
[
2
].
y
)
/
4
-
p
[
0
].
y
;
base
.
x
=
p
[
2
].
x
-
p
[
0
].
x
;
base
.
y
=
p
[
2
].
y
-
p
[
0
].
y
;
base_length
=
sqrt
(
base
.
x
*
base
.
x
+
base
.
y
*
base
.
y
);
base
.
x
/=
base_length
;
base
.
y
/=
base_length
;
dot
=
base
.
x
*
vertex
.
x
+
base
.
y
*
vertex
.
y
;
dot
=
min
(
max
(
dot
,
0
.
0
),
base_length
);
base
.
x
*=
dot
;
base
.
y
*=
dot
;
deviation
.
x
=
vertex
.
x
-
base
.
x
;
deviation
.
y
=
vertex
.
y
-
base
.
y
;
return
deviation
.
x
*
deviation
.
x
+
deviation
.
y
*
deviation
.
y
;
}
static
int
bezier_approximate
(
const
bezier_vector
*
p
,
bezier_vector
*
points
,
FLOAT
deviation
)
{
bezier_vector
first_curve
[
3
];
bezier_vector
second_curve
[
3
];
bezier_vector
vertex
;
int
total_vertices
;
if
(
bezier_deviation_squared
(
p
)
<=
deviation
*
deviation
)
{
if
(
points
)
*
points
=
p
[
2
];
return
1
;
}
vertex
.
x
=
(
p
[
0
].
x
+
p
[
1
].
x
*
2
+
p
[
2
].
x
)
/
4
;
vertex
.
y
=
(
p
[
0
].
y
+
p
[
1
].
y
*
2
+
p
[
2
].
y
)
/
4
;
first_curve
[
0
]
=
p
[
0
];
first_curve
[
1
].
x
=
(
p
[
0
].
x
+
p
[
1
].
x
)
/
2
;
first_curve
[
1
].
y
=
(
p
[
0
].
y
+
p
[
1
].
y
)
/
2
;
first_curve
[
2
]
=
vertex
;
second_curve
[
0
]
=
vertex
;
second_curve
[
1
].
x
=
(
p
[
2
].
x
+
p
[
1
].
x
)
/
2
;
second_curve
[
1
].
y
=
(
p
[
2
].
y
+
p
[
1
].
y
)
/
2
;
second_curve
[
2
]
=
p
[
2
];
total_vertices
=
bezier_approximate
(
first_curve
,
points
,
deviation
);
if
(
points
)
points
+=
total_vertices
;
total_vertices
+=
bezier_approximate
(
second_curve
,
points
,
deviation
);
return
total_vertices
;
}
/***********************************************************************
* wglUseFontOutlines_common
*/
...
...
@@ -1336,6 +1404,9 @@ static BOOL wglUseFontOutlines_common(HDC hdc,
TRACE
(
"(%p, %d, %d, %d, %f, %f, %d, %p, %s)
\n
"
,
hdc
,
first
,
count
,
listBase
,
deviation
,
extrusion
,
format
,
lpgmf
,
unicode
?
"W"
:
"A"
);
if
(
deviation
<=
0
.
0
)
deviation
=
1
.
0
/
em_size
;
if
(
!
load_libglu
())
{
ERR
(
"glu32 is required for this function but isn't available
\n
"
);
...
...
@@ -1364,7 +1435,8 @@ static BOOL wglUseFontOutlines_common(HDC hdc,
BYTE
*
buf
;
TTPOLYGONHEADER
*
pph
;
TTPOLYCURVE
*
ppc
;
GLdouble
*
vertices
;
GLdouble
*
vertices
=
NULL
;
int
vertex_total
=
-
1
;
if
(
unicode
)
needed
=
GetGlyphOutlineW
(
hdc
,
glyph
,
GGO_NATIVE
,
&
gm
,
0
,
NULL
,
&
identity
);
...
...
@@ -1375,7 +1447,6 @@ static BOOL wglUseFontOutlines_common(HDC hdc,
goto
error
;
buf
=
HeapAlloc
(
GetProcessHeap
(),
0
,
needed
);
vertices
=
HeapAlloc
(
GetProcessHeap
(),
0
,
needed
/
sizeof
(
POINTFX
)
*
3
*
sizeof
(
GLdouble
));
if
(
unicode
)
GetGlyphOutlineW
(
hdc
,
glyph
,
GGO_NATIVE
,
&
gm
,
needed
,
buf
,
&
identity
);
...
...
@@ -1398,63 +1469,116 @@ static BOOL wglUseFontOutlines_common(HDC hdc,
lpgmf
++
;
}
funcs
->
gl
.
p_glNewList
(
listBase
++
,
GL_COMPILE
);
funcs
->
gl
.
p_glNewList
(
listBase
++
,
GL_COMPILE
);
funcs
->
gl
.
p_glFrontFace
(
GL_CW
);
pgluTessBeginPolygon
(
tess
,
NULL
);
pph
=
(
TTPOLYGONHEADER
*
)
buf
;
while
((
BYTE
*
)
pph
<
buf
+
needed
)
while
(
!
vertices
)
{
TRACE
(
"
\t
start %d, %d
\n
"
,
pph
->
pfxStart
.
x
.
value
,
pph
->
pfxStart
.
y
.
value
);
if
(
vertex_total
!=
-
1
)
vertices
=
HeapAlloc
(
GetProcessHeap
(),
0
,
vertex_total
*
3
*
sizeof
(
GLdouble
));
vertex_total
=
0
;
pgluTessBeginContour
(
tess
);
pph
=
(
TTPOLYGONHEADER
*
)
buf
;
while
((
BYTE
*
)
pph
<
buf
+
needed
)
{
GLdouble
previous
[
3
];
fixed_to_double
(
pph
->
pfxStart
,
em_size
,
previous
);
fixed_to_double
(
pph
->
pfxStart
,
em_size
,
vertices
);
pgluTessVertex
(
tess
,
vertices
,
vertices
);
vertices
+=
3
;
if
(
vertices
)
TRACE
(
"
\t
start %d, %d
\n
"
,
pph
->
pfxStart
.
x
.
value
,
pph
->
pfxStart
.
y
.
value
);
ppc
=
(
TTPOLYCURVE
*
)((
char
*
)
pph
+
sizeof
(
*
pph
));
while
((
char
*
)
ppc
<
(
char
*
)
pph
+
pph
->
cb
)
{
int
i
;
switch
(
ppc
->
wType
)
{
case
TT_PRIM_LINE
:
for
(
i
=
0
;
i
<
ppc
->
cpfx
;
i
++
)
{
TRACE
(
"
\t\t
line to %d, %d
\n
"
,
ppc
->
apfx
[
i
].
x
.
value
,
ppc
->
apfx
[
i
].
y
.
value
);
fixed_to_double
(
ppc
->
apfx
[
i
],
em_size
,
vertices
);
pgluTessVertex
(
tess
,
vertices
,
vertices
);
vertices
+=
3
;
}
break
;
case
TT_PRIM_QSPLINE
:
for
(
i
=
0
;
i
<
ppc
->
cpfx
/
2
;
i
++
)
{
/* FIXME: just connecting the control points for now */
TRACE
(
"
\t\t
curve %d,%d %d,%d
\n
"
,
ppc
->
apfx
[
i
*
2
].
x
.
value
,
ppc
->
apfx
[
i
*
3
].
y
.
value
,
ppc
->
apfx
[
i
*
2
+
1
].
x
.
value
,
ppc
->
apfx
[
i
*
3
+
1
].
y
.
value
);
fixed_to_double
(
ppc
->
apfx
[
i
*
2
],
em_size
,
vertices
);
pgluTessVertex
(
tess
,
vertices
,
vertices
);
vertices
+=
3
;
fixed_to_double
(
ppc
->
apfx
[
i
*
2
+
1
],
em_size
,
vertices
);
pgluTessVertex
(
tess
,
vertices
,
vertices
);
vertices
+=
3
;
}
break
;
default:
ERR
(
"
\t\t
curve type = %d
\n
"
,
ppc
->
wType
);
pgluTessEndContour
(
tess
);
goto
error_in_list
;
pgluTessBeginContour
(
tess
);
if
(
vertices
)
{
fixed_to_double
(
pph
->
pfxStart
,
em_size
,
vertices
);
pgluTessVertex
(
tess
,
vertices
,
vertices
);
vertices
+=
3
;
}
vertex_total
++
;
ppc
=
(
TTPOLYCURVE
*
)((
char
*
)
pph
+
sizeof
(
*
pph
));
while
((
char
*
)
ppc
<
(
char
*
)
pph
+
pph
->
cb
)
{
int
i
,
j
;
int
num
;
switch
(
ppc
->
wType
)
{
case
TT_PRIM_LINE
:
for
(
i
=
0
;
i
<
ppc
->
cpfx
;
i
++
)
{
if
(
vertices
)
{
TRACE
(
"
\t\t
line to %d, %d
\n
"
,
ppc
->
apfx
[
i
].
x
.
value
,
ppc
->
apfx
[
i
].
y
.
value
);
fixed_to_double
(
ppc
->
apfx
[
i
],
em_size
,
vertices
);
pgluTessVertex
(
tess
,
vertices
,
vertices
);
vertices
+=
3
;
}
fixed_to_double
(
ppc
->
apfx
[
i
],
em_size
,
previous
);
vertex_total
++
;
}
break
;
case
TT_PRIM_QSPLINE
:
for
(
i
=
0
;
i
<
ppc
->
cpfx
-
1
;
i
++
)
{
bezier_vector
curve
[
3
];
bezier_vector
*
points
;
GLdouble
curve_vertex
[
3
];
if
(
vertices
)
TRACE
(
"
\t\t
curve %d,%d %d,%d
\n
"
,
ppc
->
apfx
[
i
].
x
.
value
,
ppc
->
apfx
[
i
].
y
.
value
,
ppc
->
apfx
[
i
+
1
].
x
.
value
,
ppc
->
apfx
[
i
+
1
].
y
.
value
);
curve
[
0
].
x
=
previous
[
0
];
curve
[
0
].
y
=
previous
[
1
];
fixed_to_double
(
ppc
->
apfx
[
i
],
em_size
,
curve_vertex
);
curve
[
1
].
x
=
curve_vertex
[
0
];
curve
[
1
].
y
=
curve_vertex
[
1
];
fixed_to_double
(
ppc
->
apfx
[
i
+
1
],
em_size
,
curve_vertex
);
curve
[
2
].
x
=
curve_vertex
[
0
];
curve
[
2
].
y
=
curve_vertex
[
1
];
if
(
i
<
ppc
->
cpfx
-
2
)
{
curve
[
2
].
x
=
(
curve
[
1
].
x
+
curve
[
2
].
x
)
/
2
;
curve
[
2
].
y
=
(
curve
[
1
].
y
+
curve
[
2
].
y
)
/
2
;
}
num
=
bezier_approximate
(
curve
,
NULL
,
deviation
);
points
=
HeapAlloc
(
GetProcessHeap
(),
0
,
num
*
sizeof
(
bezier_vector
));
num
=
bezier_approximate
(
curve
,
points
,
deviation
);
vertex_total
+=
num
;
if
(
vertices
)
{
for
(
j
=
0
;
j
<
num
;
j
++
)
{
TRACE
(
"
\t\t\t
vertex at %f,%f
\n
"
,
points
[
j
].
x
,
points
[
j
].
y
);
vertices
[
0
]
=
points
[
j
].
x
;
vertices
[
1
]
=
points
[
j
].
y
;
vertices
[
2
]
=
0
.
0
;
pgluTessVertex
(
tess
,
vertices
,
vertices
);
vertices
+=
3
;
}
}
HeapFree
(
GetProcessHeap
(),
0
,
points
);
previous
[
0
]
=
curve
[
2
].
x
;
previous
[
1
]
=
curve
[
2
].
y
;
}
break
;
default:
ERR
(
"
\t\t
curve type = %d
\n
"
,
ppc
->
wType
);
pgluTessEndContour
(
tess
);
goto
error_in_list
;
}
ppc
=
(
TTPOLYCURVE
*
)((
char
*
)
ppc
+
sizeof
(
*
ppc
)
+
(
ppc
->
cpfx
-
1
)
*
sizeof
(
POINTFX
));
ppc
=
(
TTPOLYCURVE
*
)((
char
*
)
ppc
+
sizeof
(
*
ppc
)
+
(
ppc
->
cpfx
-
1
)
*
sizeof
(
POINTFX
));
}
pgluTessEndContour
(
tess
);
pph
=
(
TTPOLYGONHEADER
*
)((
char
*
)
pph
+
pph
->
cb
);
}
pgluTessEndContour
(
tess
);
pph
=
(
TTPOLYGONHEADER
*
)((
char
*
)
pph
+
pph
->
cb
);
}
error_in_list:
...
...
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