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
170e31a8
Commit
170e31a8
authored
Nov 02, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Nov 03, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Added support for transform in glyph run analysis.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
5da26de7
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
133 additions
and
6 deletions
+133
-6
dwrite_private.h
dlls/dwrite/dwrite_private.h
+1
-0
font.c
dlls/dwrite/font.c
+28
-0
freetype.c
dlls/dwrite/freetype.c
+77
-6
font.c
dlls/dwrite/tests/font.c
+27
-0
No files found.
dlls/dwrite/dwrite_private.h
View file @
170e31a8
...
...
@@ -201,6 +201,7 @@ struct dwrite_glyphbitmap {
RECT
bbox
;
BYTE
*
buf
;
DWRITE_TEXTURE_TYPE
type
;
DWRITE_MATRIX
*
m
;
};
extern
BOOL
init_freetype
(
void
)
DECLSPEC_HIDDEN
;
...
...
dlls/dwrite/font.c
View file @
170e31a8
...
...
@@ -4084,6 +4084,8 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a
glyph_bitmap
.
emsize
=
analysis
->
run
.
fontEmSize
*
analysis
->
ppdip
;
glyph_bitmap
.
nohint
=
analysis
->
rendering_mode
==
DWRITE_RENDERING_MODE_NATURAL
||
analysis
->
rendering_mode
==
DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
;
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
glyph_bitmap
.
m
=
&
analysis
->
m
;
for
(
i
=
0
;
i
<
analysis
->
run
.
glyphCount
;
i
++
)
{
const
D2D_POINT_2F
*
advanceoffset
=
analysis
->
advanceoffsets
?
analysis
->
advanceoffsets
+
i
:
NULL
;
...
...
@@ -4126,6 +4128,8 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a
/* translate to given run origin */
OffsetRect
(
&
analysis
->
bounds
,
analysis
->
origin
.
x
,
analysis
->
origin
.
y
);
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
OffsetRect
(
&
analysis
->
bounds
,
analysis
->
m
.
dx
,
analysis
->
m
.
dy
);
analysis
->
flags
|=
RUNANALYSIS_BOUNDS_READY
;
*
bounds
=
analysis
->
bounds
;
...
...
@@ -4198,6 +4202,8 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
glyph_bitmap
.
nohint
=
analysis
->
rendering_mode
==
DWRITE_RENDERING_MODE_NATURAL
||
analysis
->
rendering_mode
==
DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
;
glyph_bitmap
.
type
=
type
;
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
glyph_bitmap
.
m
=
&
analysis
->
m
;
bbox
=
&
glyph_bitmap
.
bbox
;
for
(
i
=
0
;
i
<
analysis
->
run
.
glyphCount
;
i
++
)
{
...
...
@@ -4252,6 +4258,8 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
}
OffsetRect
(
bbox
,
analysis
->
origin
.
x
,
analysis
->
origin
.
y
);
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
OffsetRect
(
bbox
,
analysis
->
m
.
dx
,
analysis
->
m
.
dy
);
/* blit to analysis bitmap */
dst
=
get_pixel_ptr
(
analysis
->
bitmap
,
type
,
bbox
,
&
analysis
->
bounds
);
...
...
@@ -4437,6 +4445,14 @@ static inline void init_2d_vec(D2D_POINT_2F *vec, FLOAT length, BOOL is_vertical
}
}
static
inline
void
transform_2d_vec
(
D2D_POINT_2F
*
vec
,
const
DWRITE_MATRIX
*
m
)
{
D2D_POINT_2F
ret
;
ret
.
x
=
vec
->
x
*
m
->
m11
+
vec
->
y
*
m
->
m21
;
ret
.
y
=
vec
->
x
*
m
->
m12
+
vec
->
y
*
m
->
m22
;
*
vec
=
ret
;
}
HRESULT
create_glyphrunanalysis
(
DWRITE_RENDERING_MODE
rendering_mode
,
DWRITE_MEASURING_MODE
measuring_mode
,
DWRITE_GLYPH_RUN
const
*
run
,
FLOAT
ppdip
,
const
DWRITE_MATRIX
*
transform
,
DWRITE_GRID_FIT_MODE
gridfit_mode
,
DWRITE_TEXT_ANTIALIAS_MODE
aa_mode
,
FLOAT
originX
,
FLOAT
originY
,
IDWriteGlyphRunAnalysis
**
ret
)
...
...
@@ -4503,11 +4519,16 @@ HRESULT create_glyphrunanalysis(DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEA
analysis
->
run
.
glyphAdvances
=
NULL
;
analysis
->
run
.
glyphOffsets
=
NULL
;
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
transform_2d_vec
(
&
analysis
->
origin
,
&
analysis
->
m
);
memcpy
(
analysis
->
glyphs
,
run
->
glyphIndices
,
run
->
glyphCount
*
sizeof
(
*
run
->
glyphIndices
));
if
(
run
->
glyphAdvances
)
{
for
(
i
=
0
;
i
<
run
->
glyphCount
;
i
++
)
{
init_2d_vec
(
analysis
->
advances
+
i
,
run
->
glyphAdvances
[
i
]
*
ppdip
,
run
->
isSideways
);
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
transform_2d_vec
(
analysis
->
advances
+
i
,
&
analysis
->
m
);
}
}
else
{
...
...
@@ -4543,6 +4564,9 @@ HRESULT create_glyphrunanalysis(DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEA
default:
;
}
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
transform_2d_vec
(
analysis
->
advances
+
i
,
&
analysis
->
m
);
}
IDWriteFontFace1_Release
(
fontface1
);
...
...
@@ -4552,6 +4576,10 @@ HRESULT create_glyphrunanalysis(DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEA
for
(
i
=
0
;
i
<
run
->
glyphCount
;
i
++
)
{
init_2d_vec
(
analysis
->
advanceoffsets
+
i
,
run
->
glyphOffsets
[
i
].
advanceOffset
*
ppdip
,
run
->
isSideways
);
init_2d_vec
(
analysis
->
ascenderoffsets
+
i
,
run
->
glyphOffsets
[
i
].
ascenderOffset
*
ppdip
,
!
run
->
isSideways
);
if
(
analysis
->
flags
&
RUNANALYSIS_USE_TRANSFORM
)
{
transform_2d_vec
(
analysis
->
advanceoffsets
+
i
,
&
analysis
->
m
);
transform_2d_vec
(
analysis
->
ascenderoffsets
+
i
,
&
analysis
->
m
);
}
}
}
...
...
dlls/dwrite/freetype.c
View file @
170e31a8
...
...
@@ -65,10 +65,13 @@ typedef struct
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
MAKE_FUNCPTR
(
FT_Done_FreeType
);
MAKE_FUNCPTR
(
FT_Done_Glyph
);
MAKE_FUNCPTR
(
FT_Get_First_Char
);
MAKE_FUNCPTR
(
FT_Get_Kerning
);
MAKE_FUNCPTR
(
FT_Get_Sfnt_Table
);
MAKE_FUNCPTR
(
FT_Glyph_Copy
);
MAKE_FUNCPTR
(
FT_Glyph_Get_CBox
);
MAKE_FUNCPTR
(
FT_Glyph_Transform
);
MAKE_FUNCPTR
(
FT_Init_FreeType
);
MAKE_FUNCPTR
(
FT_Library_Version
);
MAKE_FUNCPTR
(
FT_Load_Glyph
);
...
...
@@ -148,10 +151,13 @@ BOOL init_freetype(void)
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ft_handle, #f, NULL, 0)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
LOAD_FUNCPTR
(
FT_Done_FreeType
)
LOAD_FUNCPTR
(
FT_Done_Glyph
)
LOAD_FUNCPTR
(
FT_Get_First_Char
)
LOAD_FUNCPTR
(
FT_Get_Kerning
)
LOAD_FUNCPTR
(
FT_Get_Sfnt_Table
)
LOAD_FUNCPTR
(
FT_Glyph_Copy
)
LOAD_FUNCPTR
(
FT_Glyph_Get_CBox
)
LOAD_FUNCPTR
(
FT_Glyph_Transform
)
LOAD_FUNCPTR
(
FT_Init_FreeType
)
LOAD_FUNCPTR
(
FT_Library_Version
)
LOAD_FUNCPTR
(
FT_Load_Glyph
)
...
...
@@ -487,20 +493,61 @@ INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2 *fontface, UINT16 le
return
adjustment
;
}
static
inline
void
ft_matrix_from_dwrite_matrix
(
const
DWRITE_MATRIX
*
m
,
FT_Matrix
*
ft_matrix
)
{
ft_matrix
->
xx
=
m
->
m11
*
0x10000
;
ft_matrix
->
xy
=
-
m
->
m21
*
0x10000
;
ft_matrix
->
yx
=
-
m
->
m12
*
0x10000
;
ft_matrix
->
yy
=
m
->
m22
*
0x10000
;
}
/* Should be used only while holding 'freetype_cs' */
static
BOOL
is_face_scalable
(
IDWriteFontFace2
*
fontface
)
{
FT_Face
face
;
if
(
pFTC_Manager_LookupFace
(
cache_manager
,
fontface
,
&
face
)
==
0
)
return
FT_IS_SCALABLE
(
face
);
else
return
FALSE
;
}
void
freetype_get_glyph_bbox
(
struct
dwrite_glyphbitmap
*
bitmap
)
{
FTC_ImageTypeRec
imagetype
;
FT_BBox
bbox
=
{
0
};
FT_Glyph
glyph
;
EnterCriticalSection
(
&
freetype_cs
);
/* Some fonts provide mostly bitmaps and very few outlines, for example for .notdef,
disable transform if that's the case. */
if
(
bitmap
->
m
)
{
if
(
!
is_face_scalable
(
bitmap
->
fontface
))
bitmap
->
m
=
NULL
;
}
imagetype
.
face_id
=
bitmap
->
fontface
;
imagetype
.
width
=
0
;
imagetype
.
height
=
bitmap
->
emsize
;
imagetype
.
flags
=
FT_LOAD_DEFAULT
;
imagetype
.
flags
=
bitmap
->
m
?
FT_LOAD_NO_BITMAP
:
FT_LOAD_DEFAULT
;
if
(
pFTC_ImageCache_Lookup
(
image_cache
,
&
imagetype
,
bitmap
->
index
,
&
glyph
,
NULL
)
==
0
)
{
if
(
bitmap
->
m
)
{
FT_Glyph
glyph_copy
;
if
(
pFT_Glyph_Copy
(
glyph
,
&
glyph_copy
)
==
0
)
{
FT_Matrix
ft_matrix
;
ft_matrix_from_dwrite_matrix
(
bitmap
->
m
,
&
ft_matrix
);
pFT_Glyph_Transform
(
glyph_copy
,
&
ft_matrix
,
NULL
);
pFT_Glyph_Get_CBox
(
glyph_copy
,
FT_GLYPH_BBOX_PIXELS
,
&
bbox
);
pFT_Done_Glyph
(
glyph_copy
);
}
}
else
pFT_Glyph_Get_CBox
(
glyph
,
FT_GLYPH_BBOX_PIXELS
,
&
bbox
);
}
EnterCriticalSection
(
&
freetype_cs
);
if
(
pFTC_ImageCache_Lookup
(
image_cache
,
&
imagetype
,
bitmap
->
index
,
&
glyph
,
NULL
)
==
0
)
pFT_Glyph_Get_CBox
(
glyph
,
FT_GLYPH_BBOX_PIXELS
,
&
bbox
);
LeaveCriticalSection
(
&
freetype_cs
);
/* flip Y axis */
...
...
@@ -607,18 +654,42 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
BOOL
ret
=
FALSE
;
FT_Glyph
glyph
;
EnterCriticalSection
(
&
freetype_cs
);
if
(
bitmap
->
m
)
{
if
(
!
is_face_scalable
(
bitmap
->
fontface
))
bitmap
->
m
=
NULL
;
}
imagetype
.
face_id
=
bitmap
->
fontface
;
imagetype
.
width
=
0
;
imagetype
.
height
=
bitmap
->
emsize
;
imagetype
.
flags
=
FT_LOAD_DEFAULT
;
imagetype
.
flags
=
bitmap
->
m
?
FT_LOAD_NO_BITMAP
:
FT_LOAD_DEFAULT
;
EnterCriticalSection
(
&
freetype_cs
);
if
(
pFTC_ImageCache_Lookup
(
image_cache
,
&
imagetype
,
bitmap
->
index
,
&
glyph
,
NULL
)
==
0
)
{
FT_Glyph
glyph_copy
;
if
(
bitmap
->
m
)
{
if
(
pFT_Glyph_Copy
(
glyph
,
&
glyph_copy
)
==
0
)
{
FT_Matrix
ft_matrix
;
ft_matrix_from_dwrite_matrix
(
bitmap
->
m
,
&
ft_matrix
);
pFT_Glyph_Transform
(
glyph_copy
,
&
ft_matrix
,
NULL
);
glyph
=
glyph_copy
;
}
}
else
glyph_copy
=
NULL
;
if
(
bitmap
->
type
==
DWRITE_TEXTURE_CLEARTYPE_3x1
)
ret
=
freetype_get_aa_glyph_bitmap
(
bitmap
,
glyph
);
else
ret
=
freetype_get_aliased_glyph_bitmap
(
bitmap
,
glyph
);
if
(
glyph_copy
)
pFT_Done_Glyph
(
glyph_copy
);
}
LeaveCriticalSection
(
&
freetype_cs
);
return
ret
;
...
...
dlls/dwrite/tests/font.c
View file @
170e31a8
...
...
@@ -3507,6 +3507,7 @@ static void test_CreateGlyphRunAnalysis(void)
DWRITE_GLYPH_OFFSET
offsets
[
2
];
DWRITE_GLYPH_METRICS
metrics
;
DWRITE_FONT_METRICS
fm
;
DWRITE_MATRIX
m
;
int
i
;
factory
=
create_factory
();
...
...
@@ -3758,6 +3759,32 @@ static void test_CreateGlyphRunAnalysis(void)
ok
((
rect
.
right
-
rect
.
left
)
>
2
*
advances
[
0
],
"got rect width %d for advance %f
\n
"
,
rect
.
right
-
rect
.
left
,
advances
[
0
]);
IDWriteGlyphRunAnalysis_Release
(
analysis
);
/* with scaling transform */
hr
=
IDWriteFactory_CreateGlyphRunAnalysis
(
factory
,
&
run
,
1
.
0
,
NULL
,
DWRITE_RENDERING_MODE_ALIASED
,
DWRITE_MEASURING_MODE_NATURAL
,
0
.
0
,
0
.
0
,
&
analysis
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
SetRectEmpty
(
&
rect
);
hr
=
IDWriteGlyphRunAnalysis_GetAlphaTextureBounds
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
rect
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
!
IsRectEmpty
(
&
rect
),
"got rect width %d
\n
"
,
rect
.
right
-
rect
.
left
);
IDWriteGlyphRunAnalysis_Release
(
analysis
);
memset
(
&
m
,
0
,
sizeof
(
m
));
m
.
m11
=
2
.
0
;
m
.
m22
=
1
.
0
;
hr
=
IDWriteFactory_CreateGlyphRunAnalysis
(
factory
,
&
run
,
1
.
0
,
&
m
,
DWRITE_RENDERING_MODE_ALIASED
,
DWRITE_MEASURING_MODE_NATURAL
,
0
.
0
,
0
.
0
,
&
analysis
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
SetRectEmpty
(
&
rect2
);
hr
=
IDWriteGlyphRunAnalysis_GetAlphaTextureBounds
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
rect2
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
((
rect2
.
right
-
rect2
.
left
)
>
(
rect
.
right
-
rect
.
left
),
"got rect width %d
\n
"
,
rect2
.
right
-
rect2
.
left
);
IDWriteGlyphRunAnalysis_Release
(
analysis
);
IDWriteFontFace_Release
(
face
);
IDWriteFactory_Release
(
factory
);
}
...
...
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