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
072a9b00
Commit
072a9b00
authored
Aug 22, 2017
by
Nikolay Sivov
Committed by
Alexandre Julliard
Aug 24, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Split initial cluster computation by stage.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
5a70c58a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
215 additions
and
172 deletions
+215
-172
analyzer.c
dlls/dwrite/analyzer.c
+2
-3
dwrite_private.h
dlls/dwrite/dwrite_private.h
+1
-1
layout.c
dlls/dwrite/layout.c
+207
-167
main.c
dlls/dwrite/main.c
+5
-1
No files found.
dlls/dwrite/analyzer.c
View file @
072a9b00
...
...
@@ -1832,10 +1832,9 @@ static const struct IDWriteTextAnalyzer2Vtbl textanalyzervtbl = {
static
IDWriteTextAnalyzer2
textanalyzer
=
{
&
textanalyzervtbl
};
HRESULT
get_textanalyzer
(
IDWriteTextAnalyzer
**
ret
)
IDWriteTextAnalyzer
*
get_text_analyzer
(
void
)
{
*
ret
=
(
IDWriteTextAnalyzer
*
)
&
textanalyzer
;
return
S_OK
;
return
(
IDWriteTextAnalyzer
*
)
&
textanalyzer
;
}
static
HRESULT
WINAPI
dwritenumbersubstitution_QueryInterface
(
IDWriteNumberSubstitution
*
iface
,
REFIID
riid
,
void
**
obj
)
...
...
dlls/dwrite/dwrite_private.h
View file @
072a9b00
...
...
@@ -175,7 +175,7 @@ extern HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLoca
extern
void
set_en_localizedstring
(
IDWriteLocalizedStrings
*
,
const
WCHAR
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
get_system_fontcollection
(
IDWriteFactory5
*
,
IDWriteFontCollection1
**
)
DECLSPEC_HIDDEN
;
extern
HRESULT
get_eudc_fontcollection
(
IDWriteFactory5
*
,
IDWriteFontCollection1
**
)
DECLSPEC_HIDDEN
;
extern
HRESULT
get_textanalyzer
(
IDWriteTextAnalyzer
**
)
DECLSPEC_HIDDEN
;
extern
IDWriteTextAnalyzer
*
get_text_analyzer
(
void
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_font_file
(
IDWriteFontFileLoader
*
loader
,
const
void
*
reference_key
,
UINT32
key_size
,
IDWriteFontFile
**
font_file
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_localfontfileloader
(
IDWriteLocalFontFileLoader
**
iface
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_fontface
(
const
struct
fontface_desc
*
,
struct
list
*
,
IDWriteFontFace4
**
)
DECLSPEC_HIDDEN
;
...
...
dlls/dwrite/layout.c
View file @
072a9b00
...
...
@@ -746,40 +746,21 @@ static void layout_get_font_height(FLOAT emsize, DWRITE_FONT_METRICS *fontmetric
*
height
=
SCALE_FONT_METRIC
(
fontmetrics
->
ascent
+
fontmetrics
->
descent
+
fontmetrics
->
lineGap
,
emsize
,
fontmetrics
);
}
static
HRESULT
layout_
compute_runs
(
struct
dwrite_textlayout
*
layout
)
static
HRESULT
layout_
itemize
(
struct
dwrite_textlayout
*
layout
)
{
IDWriteFontFallback
*
fallback
;
IDWriteTextAnalyzer
*
analyzer
;
struct
layout_range
*
range
;
struct
layout_run
*
r
;
UINT32
cluster
=
0
;
HRESULT
hr
;
free_layout_eruns
(
layout
);
free_layout_runs
(
layout
);
/* Cluster data arrays are allocated once, assuming one text position per cluster. */
if
(
!
layout
->
clustermetrics
&&
layout
->
len
)
{
layout
->
clustermetrics
=
heap_alloc
(
layout
->
len
*
sizeof
(
*
layout
->
clustermetrics
));
layout
->
clusters
=
heap_alloc
(
layout
->
len
*
sizeof
(
*
layout
->
clusters
));
if
(
!
layout
->
clustermetrics
||
!
layout
->
clusters
)
{
heap_free
(
layout
->
clustermetrics
);
heap_free
(
layout
->
clusters
);
return
E_OUTOFMEMORY
;
}
}
layout
->
cluster_count
=
0
;
HRESULT
hr
=
S_OK
;
hr
=
get_textanalyzer
(
&
analyzer
);
if
(
FAILED
(
hr
))
return
hr
;
analyzer
=
get_text_analyzer
();
LIST_FOR_EACH_ENTRY
(
range
,
&
layout
->
ranges
,
struct
layout_range
,
h
.
entry
)
{
/*
we don't care about ranges that don't contain any text
*/
/*
We don't care about ranges that don't contain any text.
*/
if
(
range
->
h
.
range
.
startPosition
>=
layout
->
len
)
break
;
/*
inline objects override actual text in a range
*/
/*
Inline objects override actual text in range.
*/
if
(
range
->
object
)
{
hr
=
layout_update_breakpoints_range
(
layout
,
range
);
if
(
FAILED
(
hr
))
...
...
@@ -795,30 +776,49 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
continue
;
}
/* initial splitting by script */
hr
=
IDWriteTextAnalyzer_AnalyzeScript
(
analyzer
,
(
IDWriteTextAnalysisSource
*
)
&
layout
->
IDWriteTextAnalysisSource1_iface
,
range
->
h
.
range
.
startPosition
,
get_clipped_range_length
(
layout
,
range
),
(
IDWriteTextAnalysisSink
*
)
&
layout
->
IDWriteTextAnalysisSink1_iface
);
/* Initial splitting by script. */
hr
=
IDWriteTextAnalyzer_AnalyzeScript
(
analyzer
,
(
IDWriteTextAnalysisSource
*
)
&
layout
->
IDWriteTextAnalysisSource1_iface
,
range
->
h
.
range
.
startPosition
,
get_clipped_range_length
(
layout
,
range
),
(
IDWriteTextAnalysisSink
*
)
&
layout
->
IDWriteTextAnalysisSink1_iface
);
if
(
FAILED
(
hr
))
break
;
/* this splits it further */
hr
=
IDWriteTextAnalyzer_AnalyzeBidi
(
analyzer
,
(
IDWriteTextAnalysisSource
*
)
&
layout
->
IDWriteTextAnalysisSource1_iface
,
range
->
h
.
range
.
startPosition
,
get_clipped_range_length
(
layout
,
range
),
(
IDWriteTextAnalysisSink
*
)
&
layout
->
IDWriteTextAnalysisSink1_iface
);
/* Splitting further by bidi levels. */
hr
=
IDWriteTextAnalyzer_AnalyzeBidi
(
analyzer
,
(
IDWriteTextAnalysisSource
*
)
&
layout
->
IDWriteTextAnalysisSource1_iface
,
range
->
h
.
range
.
startPosition
,
get_clipped_range_length
(
layout
,
range
),
(
IDWriteTextAnalysisSink
*
)
&
layout
->
IDWriteTextAnalysisSink1_iface
);
if
(
FAILED
(
hr
))
break
;
}
return
hr
;
}
static
HRESULT
layout_resolve_fonts
(
struct
dwrite_textlayout
*
layout
)
{
IDWriteFontCollection
*
sys_collection
;
IDWriteFontFallback
*
fallback
=
NULL
;
struct
layout_range
*
range
;
struct
layout_run
*
r
;
HRESULT
hr
;
if
(
FAILED
(
hr
=
IDWriteFactory5_GetSystemFontCollection
(
layout
->
factory
,
FALSE
,
(
IDWriteFontCollection1
**
)
&
sys_collection
,
FALSE
)))
{
WARN
(
"Failed to get system collection, hr %#x.
\n
"
,
hr
);
return
hr
;
}
if
(
layout
->
format
.
fallback
)
{
fallback
=
layout
->
format
.
fallback
;
IDWriteFontFallback_AddRef
(
fallback
);
}
else
{
hr
=
IDWriteFactory5_GetSystemFontFallback
(
layout
->
factory
,
&
fallback
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
FAILED
(
hr
=
IDWriteFactory5_GetSystemFontFallback
(
layout
->
factory
,
&
fallback
)))
{
WARN
(
"Failed to get system fallback, hr %#x.
\n
"
,
hr
);
goto
fatal
;
}
}
/* resolve run fonts */
LIST_FOR_EACH_ENTRY
(
r
,
&
layout
->
runs
,
struct
layout_run
,
entry
)
{
struct
regular_layout_run
*
run
=
&
r
->
u
.
regular
;
IDWriteFont
*
font
;
...
...
@@ -832,28 +832,21 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
if
(
run
->
sa
.
shapes
==
DWRITE_SCRIPT_SHAPES_NO_VISUAL
)
{
IDWriteFontCollection
*
collection
;
if
(
range
->
collection
)
{
collection
=
range
->
collection
;
IDWriteFontCollection_AddRef
(
collection
);
}
else
IDWriteFactory5_GetSystemFontCollection
(
layout
->
factory
,
FALSE
,
(
IDWriteFontCollection1
**
)
&
collection
,
FALSE
);
hr
=
create_matching_font
(
collection
,
range
->
fontfamily
,
range
->
weight
,
range
->
style
,
range
->
stretch
,
&
font
);
collection
=
range
->
collection
?
range
->
collection
:
sys_collection
;
IDWriteFontCollection_Release
(
collection
);
if
(
FAILED
(
hr
))
{
WARN
(
"%s: failed to create a font for non visual run, %s, collection %p
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
debugstr_w
(
range
->
fontfamily
),
range
->
collection
);
return
hr
;
if
(
FAILED
(
hr
=
create_matching_font
(
collection
,
range
->
fontfamily
,
range
->
weight
,
range
->
style
,
range
->
stretch
,
&
font
)))
{
WARN
(
"%s: failed to create matching font for non visual run, family %s, collection %p
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
debugstr_w
(
range
->
fontfamily
),
range
->
collection
);
break
;
}
hr
=
IDWriteFont_CreateFontFace
(
font
,
&
run
->
run
.
fontFace
);
IDWriteFont_Release
(
font
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
FAILED
(
hr
))
{
WARN
(
"Failed to create font face, hr %#x.
\n
"
,
hr
);
break
;
}
run
->
run
.
fontEmSize
=
range
->
fontsize
;
continue
;
...
...
@@ -868,7 +861,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
run
=
&
r
->
u
.
regular
;
hr
=
IDWriteFontFallback_MapCharacters
(
fallback
,
(
IDWriteTextAnalysisSource
*
)
&
layout
->
IDWriteTextAnalysisSource1_iface
,
(
IDWriteTextAnalysisSource
*
)
&
layout
->
IDWriteTextAnalysisSource1_iface
,
run
->
descr
.
textPosition
,
run
->
descr
.
stringLength
,
range
->
collection
,
...
...
@@ -880,14 +873,18 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
&
font
,
&
scale
);
if
(
FAILED
(
hr
))
{
WARN
(
"%s: failed to map family %s, collection %p
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
debugstr_w
(
range
->
fontfamily
),
range
->
collection
);
return
hr
;
WARN
(
"%s: failed to map family %s, collection %p, hr %#x.
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
debugstr_w
(
range
->
fontfamily
),
range
->
collection
,
hr
);
goto
fatal
;
}
hr
=
IDWriteFont_CreateFontFace
(
font
,
&
run
->
run
.
fontFace
);
IDWriteFont_Release
(
font
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
FAILED
(
hr
))
{
WARN
(
"Failed to create font face, hr %#x.
\n
"
,
hr
);
goto
fatal
;
}
run
->
run
.
fontEmSize
=
range
->
fontsize
*
scale
;
if
(
mapped_length
<
length
)
{
...
...
@@ -896,8 +893,10 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
/* keep mapped part for current run, add another run for the rest */
nextr
=
alloc_layout_run
(
LAYOUT_RUN_REGULAR
,
0
);
if
(
!
nextr
)
return
E_OUTOFMEMORY
;
if
(
!
nextr
)
{
hr
=
E_OUTOFMEMORY
;
goto
fatal
;
}
*
nextr
=
*
r
;
nextr
->
start_position
=
run
->
descr
.
textPosition
+
mapped_length
;
...
...
@@ -914,15 +913,150 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
}
}
IDWriteFontFallback_Release
(
fallback
);
fatal:
IDWriteFontCollection_Release
(
sys_collection
);
if
(
fallback
)
IDWriteFontFallback_Release
(
fallback
);
return
hr
;
}
static
HRESULT
layout_shape_run
(
struct
dwrite_textlayout
*
layout
,
struct
regular_layout_run
*
run
)
{
DWRITE_SHAPING_GLYPH_PROPERTIES
*
glyph_props
;
DWRITE_SHAPING_TEXT_PROPERTIES
*
text_props
;
IDWriteTextAnalyzer
*
analyzer
;
struct
layout_range
*
range
;
UINT32
max_count
;
HRESULT
hr
;
range
=
get_layout_range_by_pos
(
layout
,
run
->
descr
.
textPosition
);
run
->
descr
.
localeName
=
range
->
locale
;
run
->
clustermap
=
heap_alloc
(
run
->
descr
.
stringLength
*
sizeof
(
*
run
->
clustermap
));
max_count
=
3
*
run
->
descr
.
stringLength
/
2
+
16
;
run
->
glyphs
=
heap_alloc
(
max_count
*
sizeof
(
*
run
->
glyphs
));
if
(
!
run
->
clustermap
||
!
run
->
glyphs
)
return
E_OUTOFMEMORY
;
text_props
=
heap_alloc
(
run
->
descr
.
stringLength
*
sizeof
(
*
text_props
));
glyph_props
=
heap_alloc
(
max_count
*
sizeof
(
*
glyph_props
));
if
(
!
text_props
||
!
glyph_props
)
{
heap_free
(
text_props
);
heap_free
(
glyph_props
);
return
E_OUTOFMEMORY
;
}
analyzer
=
get_text_analyzer
();
for
(;;)
{
hr
=
IDWriteTextAnalyzer_GetGlyphs
(
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
stringLength
,
run
->
run
.
fontFace
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
/* FIXME */
,
NULL
,
NULL
,
0
,
max_count
,
run
->
clustermap
,
text_props
,
run
->
glyphs
,
glyph_props
,
&
run
->
glyphcount
);
if
(
hr
==
E_NOT_SUFFICIENT_BUFFER
)
{
heap_free
(
run
->
glyphs
);
heap_free
(
glyph_props
);
max_count
=
run
->
glyphcount
;
run
->
glyphs
=
heap_alloc
(
max_count
*
sizeof
(
*
run
->
glyphs
));
glyph_props
=
heap_alloc
(
max_count
*
sizeof
(
*
glyph_props
));
if
(
!
run
->
glyphs
||
!
glyph_props
)
{
hr
=
E_OUTOFMEMORY
;
break
;
}
continue
;
}
break
;
}
if
(
FAILED
(
hr
))
{
heap_free
(
text_props
);
heap_free
(
glyph_props
);
WARN
(
"%s: shaping failed, hr %#x.
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
hr
);
return
hr
;
}
run
->
run
.
glyphIndices
=
run
->
glyphs
;
run
->
descr
.
clusterMap
=
run
->
clustermap
;
run
->
advances
=
heap_alloc
(
run
->
glyphcount
*
sizeof
(
*
run
->
advances
));
run
->
offsets
=
heap_alloc
(
run
->
glyphcount
*
sizeof
(
*
run
->
offsets
));
if
(
!
run
->
advances
||
!
run
->
offsets
)
return
E_OUTOFMEMORY
;
/* Get advances and offsets. */
if
(
is_layout_gdi_compatible
(
layout
))
hr
=
IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements
(
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
clusterMap
,
text_props
,
run
->
descr
.
stringLength
,
run
->
run
.
glyphIndices
,
glyph_props
,
run
->
glyphcount
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
layout
->
ppdip
,
&
layout
->
transform
,
layout
->
measuringmode
==
DWRITE_MEASURING_MODE_GDI_NATURAL
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
,
NULL
,
0
,
run
->
advances
,
run
->
offsets
);
else
hr
=
IDWriteTextAnalyzer_GetGlyphPlacements
(
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
clusterMap
,
text_props
,
run
->
descr
.
stringLength
,
run
->
run
.
glyphIndices
,
glyph_props
,
run
->
glyphcount
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
,
NULL
,
0
,
run
->
advances
,
run
->
offsets
);
heap_free
(
text_props
);
heap_free
(
glyph_props
);
if
(
FAILED
(
hr
))
{
memset
(
run
->
advances
,
0
,
run
->
glyphcount
*
sizeof
(
*
run
->
advances
));
memset
(
run
->
offsets
,
0
,
run
->
glyphcount
*
sizeof
(
*
run
->
offsets
));
WARN
(
"%s: failed to get glyph placement info, hr %#x.
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
hr
);
}
run
->
run
.
glyphAdvances
=
run
->
advances
;
run
->
run
.
glyphOffsets
=
run
->
offsets
;
/* Special treatment for runs that don't produce visual output, shaping code adds normal glyphs for them,
with valid cluster map and potentially with non-zero advances; layout code exposes those as zero
width clusters. */
if
(
run
->
sa
.
shapes
==
DWRITE_SCRIPT_SHAPES_NO_VISUAL
)
run
->
run
.
glyphCount
=
0
;
else
run
->
run
.
glyphCount
=
run
->
glyphcount
;
return
S_OK
;
}
static
HRESULT
layout_compute_runs
(
struct
dwrite_textlayout
*
layout
)
{
struct
layout_run
*
r
;
UINT32
cluster
=
0
;
HRESULT
hr
;
free_layout_eruns
(
layout
);
free_layout_runs
(
layout
);
/* Cluster data arrays are allocated once, assuming one text position per cluster. */
if
(
!
layout
->
clustermetrics
&&
layout
->
len
)
{
layout
->
clustermetrics
=
heap_alloc
(
layout
->
len
*
sizeof
(
*
layout
->
clustermetrics
));
layout
->
clusters
=
heap_alloc
(
layout
->
len
*
sizeof
(
*
layout
->
clusters
));
if
(
!
layout
->
clustermetrics
||
!
layout
->
clusters
)
{
heap_free
(
layout
->
clustermetrics
);
heap_free
(
layout
->
clusters
);
return
E_OUTOFMEMORY
;
}
}
layout
->
cluster_count
=
0
;
if
(
FAILED
(
hr
=
layout_itemize
(
layout
)))
{
WARN
(
"Itemization failed, hr %#x.
\n
"
,
hr
);
return
hr
;
}
if
(
FAILED
(
hr
=
layout_resolve_fonts
(
layout
)))
{
WARN
(
"Failed to resolve layout fonts, hr %#x.
\n
"
,
hr
);
return
hr
;
}
/* fill run info */
LIST_FOR_EACH_ENTRY
(
r
,
&
layout
->
runs
,
struct
layout_run
,
entry
)
{
DWRITE_SHAPING_GLYPH_PROPERTIES
*
glyph_props
=
NULL
;
DWRITE_SHAPING_TEXT_PROPERTIES
*
text_props
=
NULL
;
struct
regular_layout_run
*
run
=
&
r
->
u
.
regular
;
DWRITE_FONT_METRICS
fontmetrics
=
{
0
};
UINT32
max_count
;
/* we need to do very little in case of inline objects */
if
(
r
->
kind
==
LAYOUT_RUN_INLINE
)
{
...
...
@@ -957,104 +1091,14 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
continue
;
}
range
=
get_layout_range_by_pos
(
layout
,
run
->
descr
.
textPosition
);
run
->
descr
.
localeName
=
range
->
locale
;
run
->
clustermap
=
heap_alloc
(
run
->
descr
.
stringLength
*
sizeof
(
UINT16
));
max_count
=
3
*
run
->
descr
.
stringLength
/
2
+
16
;
run
->
glyphs
=
heap_alloc
(
max_count
*
sizeof
(
UINT16
));
if
(
!
run
->
clustermap
||
!
run
->
glyphs
)
goto
memerr
;
text_props
=
heap_alloc
(
run
->
descr
.
stringLength
*
sizeof
(
DWRITE_SHAPING_TEXT_PROPERTIES
));
glyph_props
=
heap_alloc
(
max_count
*
sizeof
(
DWRITE_SHAPING_GLYPH_PROPERTIES
));
if
(
!
text_props
||
!
glyph_props
)
goto
memerr
;
while
(
1
)
{
hr
=
IDWriteTextAnalyzer_GetGlyphs
(
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
stringLength
,
run
->
run
.
fontFace
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
/* FIXME */
,
NULL
,
NULL
,
0
,
max_count
,
run
->
clustermap
,
text_props
,
run
->
glyphs
,
glyph_props
,
&
run
->
glyphcount
);
if
(
hr
==
E_NOT_SUFFICIENT_BUFFER
)
{
heap_free
(
run
->
glyphs
);
heap_free
(
glyph_props
);
max_count
=
run
->
glyphcount
;
run
->
glyphs
=
heap_alloc
(
max_count
*
sizeof
(
UINT16
));
glyph_props
=
heap_alloc
(
max_count
*
sizeof
(
DWRITE_SHAPING_GLYPH_PROPERTIES
));
if
(
!
run
->
glyphs
||
!
glyph_props
)
goto
memerr
;
continue
;
}
break
;
}
if
(
FAILED
(
hr
))
{
heap_free
(
text_props
);
heap_free
(
glyph_props
);
WARN
(
"%s: shaping failed 0x%08x
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
hr
);
continue
;
}
run
->
run
.
glyphIndices
=
run
->
glyphs
;
run
->
descr
.
clusterMap
=
run
->
clustermap
;
run
->
advances
=
heap_alloc
(
run
->
glyphcount
*
sizeof
(
FLOAT
));
run
->
offsets
=
heap_alloc
(
run
->
glyphcount
*
sizeof
(
DWRITE_GLYPH_OFFSET
));
if
(
!
run
->
advances
||
!
run
->
offsets
)
goto
memerr
;
/* now set advances and offsets */
if
(
is_layout_gdi_compatible
(
layout
))
hr
=
IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements
(
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
clusterMap
,
text_props
,
run
->
descr
.
stringLength
,
run
->
run
.
glyphIndices
,
glyph_props
,
run
->
glyphcount
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
layout
->
ppdip
,
&
layout
->
transform
,
layout
->
measuringmode
==
DWRITE_MEASURING_MODE_GDI_NATURAL
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
,
NULL
,
0
,
run
->
advances
,
run
->
offsets
);
else
hr
=
IDWriteTextAnalyzer_GetGlyphPlacements
(
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
clusterMap
,
text_props
,
run
->
descr
.
stringLength
,
run
->
run
.
glyphIndices
,
glyph_props
,
run
->
glyphcount
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
,
NULL
,
0
,
run
->
advances
,
run
->
offsets
);
heap_free
(
text_props
);
heap_free
(
glyph_props
);
if
(
FAILED
(
hr
))
WARN
(
"%s: failed to get glyph placement info, 0x%08x
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
hr
);
run
->
run
.
glyphAdvances
=
run
->
advances
;
run
->
run
.
glyphOffsets
=
run
->
offsets
;
/* Special treatment for runs that don't produce visual output, shaping code adds normal glyphs for them,
with valid cluster map and potentially with non-zero advances; layout code exposes those as zero width clusters. */
if
(
run
->
sa
.
shapes
==
DWRITE_SCRIPT_SHAPES_NO_VISUAL
)
run
->
run
.
glyphCount
=
0
;
else
run
->
run
.
glyphCount
=
run
->
glyphcount
;
if
(
FAILED
(
hr
=
layout_shape_run
(
layout
,
run
)))
WARN
(
"%s: shaping failed, hr %#x.
\n
"
,
debugstr_rundescr
(
&
run
->
descr
),
hr
);
/* baseline derived from font metrics */
layout_get_font_metrics
(
layout
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
&
fontmetrics
);
layout_get_font_height
(
run
->
run
.
fontEmSize
,
&
fontmetrics
,
&
r
->
baseline
,
&
r
->
height
);
layout_set_cluster_metrics
(
layout
,
r
,
&
cluster
);
continue
;
memerr:
heap_free
(
text_props
);
heap_free
(
glyph_props
);
heap_free
(
run
->
clustermap
);
heap_free
(
run
->
glyphs
);
heap_free
(
run
->
advances
);
heap_free
(
run
->
offsets
);
run
->
advances
=
NULL
;
run
->
offsets
=
NULL
;
run
->
clustermap
=
run
->
glyphs
=
NULL
;
hr
=
E_OUTOFMEMORY
;
break
;
}
if
(
hr
==
S_OK
)
{
...
...
@@ -1063,7 +1107,6 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
layout
->
clustermetrics
[
cluster
-
1
].
canWrapLineAfter
=
1
;
}
IDWriteTextAnalyzer_Release
(
analyzer
);
return
hr
;
}
...
...
@@ -1077,25 +1120,22 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout)
/* nominal breakpoints are evaluated only once, because string never changes */
if
(
!
layout
->
nominal_breakpoints
)
{
IDWriteTextAnalyzer
*
analyzer
;
HRESULT
hr
;
layout
->
nominal_breakpoints
=
heap_alloc
(
sizeof
(
DWRITE_LINE_BREAKPOINT
)
*
layout
->
len
);
layout
->
nominal_breakpoints
=
heap_alloc
(
layout
->
len
*
sizeof
(
*
layout
->
nominal_breakpoints
)
);
if
(
!
layout
->
nominal_breakpoints
)
return
E_OUTOFMEMORY
;
hr
=
get_textanalyzer
(
&
analyzer
);
if
(
FAILED
(
hr
))
return
hr
;
analyzer
=
get_text_analyzer
();
hr
=
IDWriteTextAnalyzer_AnalyzeLineBreakpoints
(
analyzer
,
(
IDWriteTextAnalysisSource
*
)
&
layout
->
IDWriteTextAnalysisSource1_iface
,
0
,
layout
->
len
,
(
IDWriteTextAnalysisSink
*
)
&
layout
->
IDWriteTextAnalysisSink1_iface
);
IDWriteTextAnalyzer_Release
(
analyzer
);
}
if
(
layout
->
actual_breakpoints
)
{
heap_free
(
layout
->
actual_breakpoints
);
layout
->
actual_breakpoints
=
NULL
;
if
(
FAILED
(
hr
=
IDWriteTextAnalyzer_AnalyzeLineBreakpoints
(
analyzer
,
(
IDWriteTextAnalysisSource
*
)
&
layout
->
IDWriteTextAnalysisSource1_iface
,
0
,
layout
->
len
,
(
IDWriteTextAnalysisSink
*
)
&
layout
->
IDWriteTextAnalysisSink1_iface
)))
WARN
(
"Line breakpoints analysis failed, hr %#x.
\n
"
,
hr
);
}
heap_free
(
layout
->
actual_breakpoints
);
layout
->
actual_breakpoints
=
NULL
;
hr
=
layout_compute_runs
(
layout
);
if
(
TRACE_ON
(
dwrite
))
{
...
...
dlls/dwrite/main.c
View file @
072a9b00
...
...
@@ -1192,8 +1192,12 @@ static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory5 *
static
HRESULT
WINAPI
dwritefactory_CreateTextAnalyzer
(
IDWriteFactory5
*
iface
,
IDWriteTextAnalyzer
**
analyzer
)
{
struct
dwritefactory
*
This
=
impl_from_IDWriteFactory5
(
iface
);
TRACE
(
"(%p)->(%p)
\n
"
,
This
,
analyzer
);
return
get_textanalyzer
(
analyzer
);
*
analyzer
=
get_text_analyzer
();
return
S_OK
;
}
static
HRESULT
WINAPI
dwritefactory_CreateNumberSubstitution
(
IDWriteFactory5
*
iface
,
...
...
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