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
ff8f129a
Commit
ff8f129a
authored
Jan 19, 2016
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jan 19, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Use callback freetype API to implement GetGlyphRunOutline().
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
f92d7726
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
169 additions
and
241 deletions
+169
-241
dwrite_private.h
dlls/dwrite/dwrite_private.h
+2
-17
font.c
dlls/dwrite/font.c
+1
-109
freetype.c
dlls/dwrite/freetype.c
+166
-115
No files found.
dlls/dwrite/dwrite_private.h
View file @
ff8f129a
...
...
@@ -175,22 +175,6 @@ extern WORD opentype_get_gasp_flags(const WORD*,UINT32,INT) DECLSPEC_HIDDEN;
extern
HRESULT
bidi_computelevels
(
const
WCHAR
*
,
UINT32
,
UINT8
,
UINT8
*
,
UINT8
*
)
DECLSPEC_HIDDEN
;
extern
WCHAR
bidi_get_mirrored_char
(
WCHAR
)
DECLSPEC_HIDDEN
;
enum
outline_point_tag
{
OUTLINE_POINT_START
=
1
<<
0
,
OUTLINE_POINT_END
=
1
<<
1
,
OUTLINE_POINT_BEZIER
=
1
<<
2
,
OUTLINE_POINT_LINE
=
1
<<
3
};
struct
glyph_outline
{
D2D1_POINT_2F
*
points
;
UINT8
*
tags
;
UINT16
count
;
FLOAT
advance
;
};
extern
HRESULT
new_glyph_outline
(
UINT32
,
struct
glyph_outline
**
)
DECLSPEC_HIDDEN
;
/* FreeType integration */
struct
dwrite_glyphbitmap
{
IDWriteFontFace2
*
fontface
;
...
...
@@ -209,7 +193,8 @@ extern void release_freetype(void) DECLSPEC_HIDDEN;
extern
HRESULT
freetype_get_design_glyph_metrics
(
IDWriteFontFace2
*
,
UINT16
,
UINT16
,
DWRITE_GLYPH_METRICS
*
)
DECLSPEC_HIDDEN
;
extern
void
freetype_notify_cacheremove
(
IDWriteFontFace2
*
)
DECLSPEC_HIDDEN
;
extern
BOOL
freetype_is_monospaced
(
IDWriteFontFace2
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
freetype_get_glyph_outline
(
IDWriteFontFace2
*
,
FLOAT
,
UINT16
,
USHORT
,
struct
glyph_outline
**
)
DECLSPEC_HIDDEN
;
extern
HRESULT
freetype_get_glyphrun_outline
(
IDWriteFontFace2
*
,
FLOAT
,
UINT16
const
*
,
FLOAT
const
*
,
DWRITE_GLYPH_OFFSET
const
*
,
UINT32
,
BOOL
,
IDWriteGeometrySink
*
)
DECLSPEC_HIDDEN
;
extern
UINT16
freetype_get_glyphcount
(
IDWriteFontFace2
*
)
DECLSPEC_HIDDEN
;
extern
UINT16
freetype_get_glyphindex
(
IDWriteFontFace2
*
,
UINT32
,
INT
)
DECLSPEC_HIDDEN
;
extern
BOOL
freetype_has_kerning_pairs
(
IDWriteFontFace2
*
)
DECLSPEC_HIDDEN
;
...
...
dlls/dwrite/font.c
View file @
ff8f129a
...
...
@@ -584,84 +584,11 @@ static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace2 *iface, void
IDWriteFontFileStream_ReleaseFileFragment
(
This
->
streams
[
0
],
table_context
);
}
HRESULT
new_glyph_outline
(
UINT32
count
,
struct
glyph_outline
**
ret
)
{
struct
glyph_outline
*
outline
;
D2D1_POINT_2F
*
points
;
UINT8
*
tags
;
*
ret
=
NULL
;
outline
=
heap_alloc
(
sizeof
(
*
outline
));
if
(
!
outline
)
return
E_OUTOFMEMORY
;
points
=
heap_alloc
(
count
*
sizeof
(
D2D1_POINT_2F
));
tags
=
heap_alloc_zero
(
count
*
sizeof
(
UINT8
));
if
(
!
points
||
!
tags
)
{
heap_free
(
points
);
heap_free
(
tags
);
heap_free
(
outline
);
return
E_OUTOFMEMORY
;
}
outline
->
points
=
points
;
outline
->
tags
=
tags
;
outline
->
count
=
count
;
outline
->
advance
=
0
.
0
f
;
*
ret
=
outline
;
return
S_OK
;
}
static
void
free_glyph_outline
(
struct
glyph_outline
*
outline
)
{
heap_free
(
outline
->
points
);
heap_free
(
outline
->
tags
);
heap_free
(
outline
);
}
static
void
report_glyph_outline
(
const
struct
glyph_outline
*
outline
,
IDWriteGeometrySink
*
sink
)
{
UINT16
p
;
for
(
p
=
0
;
p
<
outline
->
count
;
p
++
)
{
if
(
outline
->
tags
[
p
]
&
OUTLINE_POINT_START
)
{
ID2D1SimplifiedGeometrySink_BeginFigure
(
sink
,
outline
->
points
[
p
],
D2D1_FIGURE_BEGIN_FILLED
);
continue
;
}
if
(
outline
->
tags
[
p
]
&
OUTLINE_POINT_LINE
)
ID2D1SimplifiedGeometrySink_AddLines
(
sink
,
outline
->
points
+
p
,
1
);
else
if
(
outline
->
tags
[
p
]
&
OUTLINE_POINT_BEZIER
)
{
static
const
UINT16
segment_length
=
3
;
ID2D1SimplifiedGeometrySink_AddBeziers
(
sink
,
(
D2D1_BEZIER_SEGMENT
*
)
&
outline
->
points
[
p
],
1
);
p
+=
segment_length
-
1
;
}
if
(
outline
->
tags
[
p
]
&
OUTLINE_POINT_END
)
ID2D1SimplifiedGeometrySink_EndFigure
(
sink
,
D2D1_FIGURE_END_CLOSED
);
}
}
static
inline
void
translate_glyph_outline
(
struct
glyph_outline
*
outline
,
FLOAT
xoffset
,
FLOAT
yoffset
)
{
UINT16
p
;
for
(
p
=
0
;
p
<
outline
->
count
;
p
++
)
{
outline
->
points
[
p
].
x
+=
xoffset
;
outline
->
points
[
p
].
y
+=
yoffset
;
}
}
static
HRESULT
WINAPI
dwritefontface_GetGlyphRunOutline
(
IDWriteFontFace2
*
iface
,
FLOAT
emSize
,
UINT16
const
*
glyphs
,
FLOAT
const
*
advances
,
DWRITE_GLYPH_OFFSET
const
*
offsets
,
UINT32
count
,
BOOL
is_sideways
,
BOOL
is_rtl
,
IDWriteGeometrySink
*
sink
)
{
struct
dwrite_fontface
*
This
=
impl_from_IDWriteFontFace2
(
iface
);
FLOAT
advance
=
0
.
0
f
;
HRESULT
hr
;
UINT32
g
;
TRACE
(
"(%p)->(%.2f %p %p %p %u %d %d %p)
\n
"
,
This
,
emSize
,
glyphs
,
advances
,
offsets
,
count
,
is_sideways
,
is_rtl
,
sink
);
...
...
@@ -672,42 +599,7 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace2 *iface,
if
(
is_sideways
)
FIXME
(
"sideways mode is not supported.
\n
"
);
if
(
count
)
ID2D1SimplifiedGeometrySink_SetFillMode
(
sink
,
D2D1_FILL_MODE_WINDING
);
for
(
g
=
0
;
g
<
count
;
g
++
)
{
FLOAT
xoffset
=
0
.
0
f
,
yoffset
=
0
.
0
f
;
struct
glyph_outline
*
outline
;
/* FIXME: cache outlines */
hr
=
freetype_get_glyph_outline
(
iface
,
emSize
,
glyphs
[
g
],
This
->
simulations
,
&
outline
);
if
(
FAILED
(
hr
))
return
hr
;
/* glyph offsets act as current glyph adjustment */
if
(
offsets
)
{
xoffset
+=
is_rtl
?
-
offsets
[
g
].
advanceOffset
:
offsets
[
g
].
advanceOffset
;
yoffset
-=
offsets
[
g
].
ascenderOffset
;
}
if
(
g
==
0
)
advance
=
is_rtl
?
-
outline
->
advance
:
0
.
0
f
;
xoffset
+=
advance
;
translate_glyph_outline
(
outline
,
xoffset
,
yoffset
);
/* update advance to next glyph */
if
(
advances
)
advance
+=
is_rtl
?
-
advances
[
g
]
:
advances
[
g
];
else
advance
+=
is_rtl
?
-
outline
->
advance
:
outline
->
advance
;
report_glyph_outline
(
outline
,
sink
);
free_glyph_outline
(
outline
);
}
return
S_OK
;
return
freetype_get_glyphrun_outline
(
iface
,
emSize
,
glyphs
,
advances
,
offsets
,
count
,
is_rtl
,
sink
);
}
static
DWRITE_RENDERING_MODE
fontface_renderingmode_from_measuringmode
(
DWRITE_MEASURING_MODE
measuring
,
...
...
dlls/dwrite/freetype.c
View file @
ff8f129a
...
...
@@ -77,6 +77,7 @@ MAKE_FUNCPTR(FT_Library_Version);
MAKE_FUNCPTR
(
FT_Load_Glyph
);
MAKE_FUNCPTR
(
FT_New_Memory_Face
);
MAKE_FUNCPTR
(
FT_Outline_Copy
);
MAKE_FUNCPTR
(
FT_Outline_Decompose
);
MAKE_FUNCPTR
(
FT_Outline_Done
);
MAKE_FUNCPTR
(
FT_Outline_Get_Bitmap
);
MAKE_FUNCPTR
(
FT_Outline_New
);
...
...
@@ -163,6 +164,7 @@ BOOL init_freetype(void)
LOAD_FUNCPTR
(
FT_Load_Glyph
)
LOAD_FUNCPTR
(
FT_New_Memory_Face
)
LOAD_FUNCPTR
(
FT_Outline_Copy
)
LOAD_FUNCPTR
(
FT_Outline_Decompose
)
LOAD_FUNCPTR
(
FT_Outline_Done
)
LOAD_FUNCPTR
(
FT_Outline_Get_Bitmap
)
LOAD_FUNCPTR
(
FT_Outline_New
)
...
...
@@ -267,16 +269,69 @@ BOOL freetype_is_monospaced(IDWriteFontFace2 *fontface)
return
is_monospaced
;
}
static
inline
void
ft_vector_to_d2d_point
(
const
FT_Vector
*
v
,
D2D1_POINT_2F
*
p
)
struct
decompose_context
{
IDWriteGeometrySink
*
sink
;
FLOAT
xoffset
;
FLOAT
yoffset
;
BOOL
figure_started
;
BOOL
figure_closed
;
BOOL
move_to
;
/* last call was 'move_to' */
FT_Vector
origin
;
/* 'pen' position from last call */
};
static
inline
void
ft_vector_to_d2d_point
(
const
FT_Vector
*
v
,
FLOAT
xoffset
,
FLOAT
yoffset
,
D2D1_POINT_2F
*
p
)
{
p
->
x
=
v
->
x
/
64
.
0
f
;
p
->
y
=
v
->
y
/
64
.
0
f
;
p
->
x
=
(
v
->
x
/
64
.
0
f
)
+
xoffset
;
p
->
y
=
(
v
->
y
/
64
.
0
f
)
+
yoffset
;
}
/* Convert the quadratic Beziers to cubic Beziers. */
static
void
get_cubic_glyph_outline
(
const
FT_Outline
*
outline
,
short
point
,
short
first_pt
,
short
contour
,
FT_Vector
*
cubic_control
)
static
int
decompose_move_to
(
const
FT_Vector
*
to
,
void
*
user
)
{
struct
decompose_context
*
ctxt
=
(
struct
decompose_context
*
)
user
;
D2D1_POINT_2F
point
;
if
(
ctxt
->
figure_started
)
{
ID2D1SimplifiedGeometrySink_EndFigure
(
ctxt
->
sink
,
D2D1_FIGURE_END_CLOSED
);
ctxt
->
figure_closed
=
TRUE
;
}
else
ctxt
->
figure_closed
=
FALSE
;
ctxt
->
figure_started
=
TRUE
;
ft_vector_to_d2d_point
(
to
,
ctxt
->
xoffset
,
ctxt
->
yoffset
,
&
point
);
ID2D1SimplifiedGeometrySink_BeginFigure
(
ctxt
->
sink
,
point
,
D2D1_FIGURE_BEGIN_FILLED
);
ctxt
->
move_to
=
TRUE
;
ctxt
->
origin
=
*
to
;
return
0
;
}
static
int
decompose_line_to
(
const
FT_Vector
*
to
,
void
*
user
)
{
struct
decompose_context
*
ctxt
=
(
struct
decompose_context
*
)
user
;
/* special case for empty contours, in a way freetype returns them */
if
(
ctxt
->
move_to
&&
!
memcmp
(
to
,
&
ctxt
->
origin
,
sizeof
(
*
to
)))
{
ID2D1SimplifiedGeometrySink_EndFigure
(
ctxt
->
sink
,
D2D1_FIGURE_END_CLOSED
);
ctxt
->
figure_closed
=
TRUE
;
}
else
{
D2D1_POINT_2F
point
;
ft_vector_to_d2d_point
(
to
,
ctxt
->
xoffset
,
ctxt
->
yoffset
,
&
point
);
ID2D1SimplifiedGeometrySink_AddLines
(
ctxt
->
sink
,
&
point
,
1
);
ctxt
->
figure_closed
=
FALSE
;
}
ctxt
->
move_to
=
FALSE
;
ctxt
->
origin
=
*
to
;
return
0
;
}
static
int
decompose_conic_to
(
const
FT_Vector
*
control
,
const
FT_Vector
*
to
,
void
*
user
)
{
struct
decompose_context
*
ctxt
=
(
struct
decompose_context
*
)
user
;
D2D1_POINT_2F
points
[
3
];
FT_Vector
cubic
[
3
];
/* convert from quadratic to cubic */
/*
The parametric eqn for a cubic Bezier is, from PLRM:
r(t) = at^3 + bt^2 + ct + r0
...
...
@@ -294,108 +349,85 @@ static void get_cubic_glyph_outline(const FT_Outline *outline, short point, shor
and of course r0 = p0, r3 = p2
*/
/* FIXME: Possible optimization in endpoint calculation
if there are two consecutive curves */
cubic_control
[
0
]
=
outline
->
points
[
point
-
1
];
if
(
!
(
outline
->
tags
[
point
-
1
]
&
FT_Curve_Tag_On
))
{
cubic_control
[
0
].
x
+=
outline
->
points
[
point
].
x
+
1
;
cubic_control
[
0
].
y
+=
outline
->
points
[
point
].
y
+
1
;
cubic_control
[
0
].
x
>>=
1
;
cubic_control
[
0
].
y
>>=
1
;
}
if
(
point
+
1
>
outline
->
contours
[
contour
])
cubic_control
[
3
]
=
outline
->
points
[
first_pt
];
else
{
cubic_control
[
3
]
=
outline
->
points
[
point
+
1
];
if
(
!
(
outline
->
tags
[
point
+
1
]
&
FT_Curve_Tag_On
))
{
cubic_control
[
3
].
x
+=
outline
->
points
[
point
].
x
+
1
;
cubic_control
[
3
].
y
+=
outline
->
points
[
point
].
y
+
1
;
cubic_control
[
3
].
x
>>=
1
;
cubic_control
[
3
].
y
>>=
1
;
}
}
/* r1 = 1/3 p0 + 2/3 p1
r2 = 1/3 p2 + 2/3 p1 */
cubic_control
[
1
].
x
=
(
2
*
outline
->
points
[
point
].
x
+
1
)
/
3
;
cubic_control
[
1
].
y
=
(
2
*
outline
->
points
[
point
].
y
+
1
)
/
3
;
cubic_control
[
2
]
=
cubic_control
[
1
];
cubic_control
[
1
].
x
+=
(
cubic_control
[
0
].
x
+
1
)
/
3
;
cubic_control
[
1
].
y
+=
(
cubic_control
[
0
].
y
+
1
)
/
3
;
cubic_control
[
2
].
x
+=
(
cubic_control
[
3
].
x
+
1
)
/
3
;
cubic_control
[
2
].
y
+=
(
cubic_control
[
3
].
y
+
1
)
/
3
;
}
static
short
get_outline_data
(
const
FT_Outline
*
outline
,
struct
glyph_outline
*
ret
)
{
short
contour
,
point
=
0
,
first_pt
,
count
;
for
(
contour
=
0
,
count
=
0
;
contour
<
outline
->
n_contours
;
contour
++
)
{
first_pt
=
point
;
if
(
ret
)
{
ft_vector_to_d2d_point
(
&
outline
->
points
[
point
],
&
ret
->
points
[
count
]);
ret
->
tags
[
count
]
=
OUTLINE_POINT_START
;
if
(
count
)
ret
->
tags
[
count
-
1
]
|=
OUTLINE_POINT_END
;
}
cubic
[
0
].
x
=
(
2
*
control
->
x
+
1
)
/
3
;
cubic
[
0
].
y
=
(
2
*
control
->
y
+
1
)
/
3
;
cubic
[
1
]
=
cubic
[
0
];
cubic
[
0
].
x
+=
(
ctxt
->
origin
.
x
+
1
)
/
3
;
cubic
[
0
].
y
+=
(
ctxt
->
origin
.
y
+
1
)
/
3
;
cubic
[
1
].
x
+=
(
to
->
x
+
1
)
/
3
;
cubic
[
1
].
y
+=
(
to
->
y
+
1
)
/
3
;
cubic
[
2
]
=
*
to
;
ft_vector_to_d2d_point
(
cubic
,
ctxt
->
xoffset
,
ctxt
->
yoffset
,
points
);
ft_vector_to_d2d_point
(
cubic
+
1
,
ctxt
->
xoffset
,
ctxt
->
yoffset
,
points
+
1
);
ft_vector_to_d2d_point
(
cubic
+
2
,
ctxt
->
xoffset
,
ctxt
->
yoffset
,
points
+
2
);
ID2D1SimplifiedGeometrySink_AddBeziers
(
ctxt
->
sink
,
(
D2D1_BEZIER_SEGMENT
*
)
points
,
1
);
ctxt
->
figure_closed
=
FALSE
;
ctxt
->
move_to
=
FALSE
;
ctxt
->
origin
=
*
to
;
return
0
;
}
point
++
;
count
++
;
static
int
decompose_cubic_to
(
const
FT_Vector
*
control1
,
const
FT_Vector
*
control2
,
const
FT_Vector
*
to
,
void
*
user
)
{
struct
decompose_context
*
ctxt
=
(
struct
decompose_context
*
)
user
;
D2D1_POINT_2F
points
[
3
];
while
(
point
<=
outline
->
contours
[
contour
])
{
do
{
if
(
outline
->
tags
[
point
]
&
FT_Curve_Tag_On
)
{
if
(
ret
)
{
ft_vector_to_d2d_point
(
&
outline
->
points
[
point
],
&
ret
->
points
[
count
]);
ret
->
tags
[
count
]
|=
OUTLINE_POINT_LINE
;
}
ft_vector_to_d2d_point
(
control1
,
ctxt
->
xoffset
,
ctxt
->
yoffset
,
points
);
ft_vector_to_d2d_point
(
control2
,
ctxt
->
xoffset
,
ctxt
->
yoffset
,
points
+
1
);
ft_vector_to_d2d_point
(
to
,
ctxt
->
xoffset
,
ctxt
->
yoffset
,
points
+
2
);
ID2D1SimplifiedGeometrySink_AddBeziers
(
ctxt
->
sink
,
(
D2D1_BEZIER_SEGMENT
*
)
points
,
1
);
ctxt
->
figure_closed
=
FALSE
;
ctxt
->
move_to
=
FALSE
;
ctxt
->
origin
=
*
to
;
return
0
;
}
point
++
;
count
++
;
}
else
{
if
(
ret
)
{
FT_Vector
cubic_control
[
4
];
get_cubic_glyph_outline
(
outline
,
point
,
first_pt
,
contour
,
cubic_control
);
ft_vector_to_d2d_point
(
&
cubic_control
[
1
],
&
ret
->
points
[
count
]);
ft_vector_to_d2d_point
(
&
cubic_control
[
2
],
&
ret
->
points
[
count
+
1
]);
ft_vector_to_d2d_point
(
&
cubic_control
[
3
],
&
ret
->
points
[
count
+
2
]);
ret
->
tags
[
count
]
=
OUTLINE_POINT_BEZIER
;
ret
->
tags
[
count
+
1
]
=
OUTLINE_POINT_BEZIER
;
ret
->
tags
[
count
+
2
]
=
OUTLINE_POINT_BEZIER
;
}
count
+=
3
;
point
++
;
}
}
while
(
point
<=
outline
->
contours
[
contour
]
&&
(
outline
->
tags
[
point
]
&
FT_Curve_Tag_On
)
==
(
outline
->
tags
[
point
-
1
]
&
FT_Curve_Tag_On
));
if
(
point
<=
outline
->
contours
[
contour
]
&&
outline
->
tags
[
point
]
&
FT_Curve_Tag_On
)
{
/* This is the closing pt of a bezier, but we've already
added it, so just inc point and carry on */
point
++
;
}
}
}
static
void
decompose_outline
(
FT_Outline
*
outline
,
FLOAT
xoffset
,
FLOAT
yoffset
,
IDWriteGeometrySink
*
sink
)
{
static
const
FT_Outline_Funcs
decompose_funcs
=
{
decompose_move_to
,
decompose_line_to
,
decompose_conic_to
,
decompose_cubic_to
,
0
,
0
};
struct
decompose_context
context
;
if
(
ret
)
ret
->
tags
[
count
-
1
]
|=
OUTLINE_POINT_END
;
context
.
sink
=
sink
;
context
.
xoffset
=
xoffset
;
context
.
yoffset
=
yoffset
;
context
.
figure_started
=
FALSE
;
context
.
figure_closed
=
FALSE
;
context
.
move_to
=
FALSE
;
context
.
origin
.
x
=
0
;
context
.
origin
.
y
=
0
;
return
count
;
pFT_Outline_Decompose
(
outline
,
&
decompose_funcs
,
&
context
);
if
(
!
context
.
figure_closed
&&
outline
->
n_points
)
ID2D1SimplifiedGeometrySink_EndFigure
(
sink
,
D2D1_FIGURE_END_CLOSED
);
}
HRESULT
freetype_get_glyph_outline
(
IDWriteFontFace2
*
fontface
,
FLOAT
emSize
,
UINT16
index
,
USHORT
simulations
,
struct
glyph_outline
**
ret
)
HRESULT
freetype_get_glyphrun_outline
(
IDWriteFontFace2
*
fontface
,
FLOAT
emSize
,
UINT16
const
*
glyphs
,
FLOAT
const
*
advances
,
DWRITE_GLYPH_OFFSET
const
*
offsets
,
UINT32
count
,
BOOL
is_rtl
,
IDWriteGeometrySink
*
sink
)
{
FTC_ScalerRec
scaler
;
USHORT
simulations
;
HRESULT
hr
=
S_OK
;
FT_Size
size
;
if
(
!
count
)
return
S_OK
;
ID2D1SimplifiedGeometrySink_SetFillMode
(
sink
,
D2D1_FILL_MODE_WINDING
);
simulations
=
IDWriteFontFace2_GetSimulations
(
fontface
);
scaler
.
face_id
=
fontface
;
scaler
.
width
=
emSize
;
scaler
.
height
=
emSize
;
...
...
@@ -405,26 +437,45 @@ HRESULT freetype_get_glyph_outline(IDWriteFontFace2 *fontface, FLOAT emSize, UIN
EnterCriticalSection
(
&
freetype_cs
);
if
(
pFTC_Manager_LookupSize
(
cache_manager
,
&
scaler
,
&
size
)
==
0
)
{
if
(
pFT_Load_Glyph
(
size
->
face
,
index
,
FT_LOAD_NO_BITMAP
)
==
0
)
{
FT_Outline
*
outline
=
&
size
->
face
->
glyph
->
outline
;
short
count
;
FT_Matrix
m
;
m
.
xx
=
1
<<
16
;
m
.
xy
=
simulations
&
DWRITE_FONT_SIMULATIONS_OBLIQUE
?
(
1
<<
16
)
/
3
:
0
;
m
.
yx
=
0
;
m
.
yy
=
-
(
1
<<
16
);
/* flip Y axis */
pFT_Outline_Transform
(
outline
,
&
m
);
count
=
get_outline_data
(
outline
,
NULL
);
hr
=
new_glyph_outline
(
count
,
ret
);
if
(
hr
==
S_OK
)
{
get_outline_data
(
outline
,
*
ret
);
(
*
ret
)
->
advance
=
size
->
face
->
glyph
->
metrics
.
horiAdvance
>>
6
;
}
}
FLOAT
advance
=
0
.
0
f
;
UINT32
g
;
for
(
g
=
0
;
g
<
count
;
g
++
)
{
if
(
pFT_Load_Glyph
(
size
->
face
,
glyphs
[
g
],
FT_LOAD_NO_BITMAP
)
==
0
)
{
FLOAT
ft_advance
=
size
->
face
->
glyph
->
metrics
.
horiAdvance
>>
6
;
FT_Outline
*
outline
=
&
size
->
face
->
glyph
->
outline
;
FLOAT
xoffset
=
0
.
0
f
,
yoffset
=
0
.
0
f
;
FT_Matrix
m
;
m
.
xx
=
1
<<
16
;
m
.
xy
=
simulations
&
DWRITE_FONT_SIMULATIONS_OBLIQUE
?
(
1
<<
16
)
/
3
:
0
;
m
.
yx
=
0
;
m
.
yy
=
-
(
1
<<
16
);
/* flip Y axis */
pFT_Outline_Transform
(
outline
,
&
m
);
/* glyph offsets act as current glyph adjustment */
if
(
offsets
)
{
xoffset
+=
is_rtl
?
-
offsets
[
g
].
advanceOffset
:
offsets
[
g
].
advanceOffset
;
yoffset
-=
offsets
[
g
].
ascenderOffset
;
}
if
(
g
==
0
&&
is_rtl
)
advance
=
advances
?
-
advances
[
g
]
:
-
ft_advance
;
xoffset
+=
advance
;
decompose_outline
(
outline
,
xoffset
,
yoffset
,
sink
);
/* update advance to next glyph */
if
(
advances
)
advance
+=
is_rtl
?
-
advances
[
g
]
:
advances
[
g
];
else
advance
+=
is_rtl
?
-
ft_advance
:
ft_advance
;
}
}
}
else
hr
=
E_FAIL
;
LeaveCriticalSection
(
&
freetype_cs
);
return
hr
;
...
...
@@ -775,9 +826,9 @@ BOOL freetype_is_monospaced(IDWriteFontFace2 *fontface)
return
FALSE
;
}
HRESULT
freetype_get_glyph_outline
(
IDWriteFontFace2
*
fontface
,
FLOAT
emSize
,
UINT16
index
,
USHORT
simulations
,
struct
glyph_outline
**
ret
)
HRESULT
freetype_get_glyphrun_outline
(
IDWriteFontFace2
*
fontface
,
FLOAT
emSize
,
UINT16
const
*
glyphs
,
FLOAT
const
*
advances
,
DWRITE_GLYPH_OFFSET
const
*
offsets
,
UINT32
count
,
BOOL
is_rtl
,
IDWriteGeometrySink
*
sink
)
{
*
ret
=
NULL
;
return
E_NOTIMPL
;
}
...
...
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