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
44c301c5
Commit
44c301c5
authored
Jul 31, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jul 31, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Implement DrawGlyphRun().
parent
e08b77b0
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
154 additions
and
17 deletions
+154
-17
gdiinterop.c
dlls/dwrite/gdiinterop.c
+154
-17
No files found.
dlls/dwrite/gdiinterop.c
View file @
44c301c5
/*
* GDI Interop
*
* Copyright 2011 Huw Davies
* Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
*
* This library is free software; you can redistribute it and/or
...
...
@@ -36,17 +37,30 @@ struct gdiinterop {
IDWriteFactory2
*
factory
;
};
struct
dib_data
{
DWORD
*
ptr
;
int
stride
;
int
width
;
};
struct
rendertarget
{
IDWriteBitmapRenderTarget1
IDWriteBitmapRenderTarget1_iface
;
LONG
ref
;
IDWriteFactory
*
factory
;
DWRITE_TEXT_ANTIALIAS_MODE
antialiasmode
;
FLOAT
p
ixels_per_
dip
;
FLOAT
p
p
dip
;
DWRITE_MATRIX
m
;
SIZE
size
;
HDC
hdc
;
struct
dib_data
dib
;
};
static
inline
int
get_dib_stride
(
int
width
,
int
bpp
)
{
return
((
width
*
bpp
+
31
)
>>
3
)
&
~
3
;
}
static
HRESULT
create_target_dibsection
(
struct
rendertarget
*
target
,
UINT32
width
,
UINT32
height
)
{
char
bmibuf
[
FIELD_OFFSET
(
BITMAPINFO
,
bmiColors
[
256
])];
...
...
@@ -64,9 +78,17 @@ static HRESULT create_target_dibsection(struct rendertarget *target, UINT32 widt
bmi
->
bmiHeader
.
biPlanes
=
1
;
bmi
->
bmiHeader
.
biCompression
=
BI_RGB
;
hbm
=
CreateDIBSection
(
target
->
hdc
,
bmi
,
DIB_RGB_COLORS
,
NULL
,
NULL
,
0
);
if
(
!
hbm
)
hbm
=
CreateDIBSection
(
target
->
hdc
,
bmi
,
DIB_RGB_COLORS
,
(
void
**
)
&
target
->
dib
.
ptr
,
NULL
,
0
);
if
(
!
hbm
)
{
hbm
=
CreateBitmap
(
1
,
1
,
1
,
1
,
NULL
);
target
->
dib
.
ptr
=
NULL
;
target
->
dib
.
stride
=
0
;
target
->
dib
.
width
=
0
;
}
else
{
target
->
dib
.
stride
=
get_dib_stride
(
width
,
32
);
target
->
dib
.
width
=
width
;
}
DeleteObject
(
SelectObject
(
target
->
hdc
,
hbm
));
return
S_OK
;
...
...
@@ -119,6 +141,7 @@ static ULONG WINAPI rendertarget_Release(IDWriteBitmapRenderTarget1 *iface)
if
(
!
ref
)
{
IDWriteFactory_Release
(
This
->
factory
);
DeleteDC
(
This
->
hdc
);
heap_free
(
This
);
}
...
...
@@ -126,15 +149,127 @@ static ULONG WINAPI rendertarget_Release(IDWriteBitmapRenderTarget1 *iface)
return
ref
;
}
static
inline
DWORD
*
get_pixel_ptr_32
(
struct
dib_data
*
dib
,
int
x
,
int
y
)
{
return
(
DWORD
*
)((
BYTE
*
)
dib
->
ptr
+
y
*
dib
->
stride
+
x
*
4
);
}
static
void
blit_8
(
struct
dib_data
*
dib
,
const
BYTE
*
src
,
const
RECT
*
rect
,
DWORD
text_pixel
)
{
DWORD
*
dst_ptr
=
get_pixel_ptr_32
(
dib
,
rect
->
left
,
rect
->
top
);
int
x
,
y
,
src_width
=
rect
->
right
-
rect
->
left
;
for
(
y
=
rect
->
top
;
y
<
rect
->
bottom
;
y
++
)
{
for
(
x
=
0
;
x
<
src_width
;
x
++
)
{
if
(
src
[
x
]
<
DWRITE_ALPHA_MAX
)
continue
;
dst_ptr
[
x
]
=
text_pixel
;
}
src
+=
src_width
;
dst_ptr
+=
dib
->
stride
/
4
;
}
}
static
inline
BYTE
blend_color
(
BYTE
dst
,
BYTE
src
,
BYTE
alpha
)
{
return
(
src
*
alpha
+
dst
*
(
255
-
alpha
)
+
127
)
/
255
;
}
static
inline
DWORD
blend_subpixel
(
BYTE
r
,
BYTE
g
,
BYTE
b
,
DWORD
text
,
const
BYTE
*
alpha
)
{
return
blend_color
(
r
,
text
>>
16
,
alpha
[
0
])
<<
16
|
blend_color
(
g
,
text
>>
8
,
alpha
[
1
])
<<
8
|
blend_color
(
b
,
text
,
alpha
[
2
]);
}
static
void
blit_subpixel_888
(
struct
dib_data
*
dib
,
int
dib_width
,
const
BYTE
*
src
,
const
RECT
*
rect
,
DWORD
text_pixel
)
{
DWORD
*
dst_ptr
=
get_pixel_ptr_32
(
dib
,
rect
->
left
,
rect
->
top
);
int
x
,
y
,
src_width
=
rect
->
right
-
rect
->
left
;
for
(
y
=
rect
->
top
;
y
<
rect
->
bottom
;
y
++
)
{
for
(
x
=
0
;
x
<
src_width
;
x
++
)
{
if
(
src
[
3
*
x
]
==
0
&&
src
[
3
*
x
+
1
]
==
0
&&
src
[
3
*
x
+
2
]
==
0
)
continue
;
dst_ptr
[
x
]
=
blend_subpixel
(
dst_ptr
[
x
]
>>
16
,
dst_ptr
[
x
]
>>
8
,
dst_ptr
[
x
],
text_pixel
,
&
src
[
3
*
x
]);
}
dst_ptr
+=
dib
->
stride
/
4
;
src
+=
src_width
*
3
;
}
}
static
HRESULT
WINAPI
rendertarget_DrawGlyphRun
(
IDWriteBitmapRenderTarget1
*
iface
,
FLOAT
baselineOriginX
,
FLOAT
baselineO
riginY
,
DWRITE_MEASURING_MODE
measuring_mode
,
DWRITE_GLYPH_RUN
const
*
glyph_run
,
IDWriteRenderingParams
*
params
,
COLORREF
textC
olor
,
RECT
*
b
lackbox_rec
t
)
FLOAT
originX
,
FLOAT
o
riginY
,
DWRITE_MEASURING_MODE
measuring_mode
,
DWRITE_GLYPH_RUN
const
*
run
,
IDWriteRenderingParams
*
params
,
COLORREF
c
olor
,
RECT
*
b
box_re
t
)
{
struct
rendertarget
*
This
=
impl_from_IDWriteBitmapRenderTarget1
(
iface
);
FIXME
(
"(%p)->(%f %f %d %p %p 0x%08x %p): stub
\n
"
,
This
,
baselineOriginX
,
baselineOriginY
,
measuring_mode
,
glyph_run
,
params
,
textColor
,
blackbox_rect
);
return
E_NOTIMPL
;
IDWriteGlyphRunAnalysis
*
analysis
;
DWRITE_RENDERING_MODE
rendermode
;
DWRITE_TEXTURE_TYPE
texturetype
;
RECT
target
,
bounds
;
HRESULT
hr
;
TRACE
(
"(%p)->(%.2f %.2f %d %p %p 0x%08x %p)
\n
"
,
This
,
originX
,
originY
,
measuring_mode
,
run
,
params
,
color
,
bbox_ret
);
if
(
!
This
->
dib
.
ptr
)
return
S_OK
;
hr
=
IDWriteFontFace_GetRecommendedRenderingMode
(
run
->
fontFace
,
run
->
fontEmSize
,
This
->
ppdip
,
measuring_mode
,
params
,
&
rendermode
);
if
(
FAILED
(
hr
))
return
hr
;
/* FIXME: outline mode rendering is not supported for this target yet */
if
(
rendermode
==
DWRITE_RENDERING_MODE_OUTLINE
)
rendermode
=
DWRITE_RENDERING_MODE_ALIASED
;
hr
=
IDWriteFactory_CreateGlyphRunAnalysis
(
This
->
factory
,
run
,
This
->
ppdip
,
&
This
->
m
,
rendermode
,
measuring_mode
,
originX
,
originY
,
&
analysis
);
if
(
FAILED
(
hr
))
{
WARN
(
"failed to create analysis instance, 0x%08x
\n
"
,
hr
);
return
hr
;
}
SetRectEmpty
(
&
bounds
);
texturetype
=
DWRITE_TEXTURE_ALIASED_1x1
;
hr
=
IDWriteGlyphRunAnalysis_GetAlphaTextureBounds
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
bounds
);
if
(
FAILED
(
hr
)
||
IsRectEmpty
(
&
bounds
))
{
hr
=
IDWriteGlyphRunAnalysis_GetAlphaTextureBounds
(
analysis
,
DWRITE_TEXTURE_CLEARTYPE_3x1
,
&
bounds
);
texturetype
=
DWRITE_TEXTURE_CLEARTYPE_3x1
;
}
target
.
left
=
target
.
top
=
0
;
target
.
right
=
This
->
size
.
cx
;
target
.
bottom
=
This
->
size
.
cy
;
SetRectEmpty
(
bbox_ret
);
if
(
IntersectRect
(
&
target
,
&
target
,
&
bounds
))
{
UINT32
size
=
(
target
.
right
-
target
.
left
)
*
(
target
.
bottom
-
target
.
top
);
BYTE
*
bitmap
;
if
(
texturetype
==
DWRITE_TEXTURE_CLEARTYPE_3x1
)
size
*=
3
;
bitmap
=
heap_alloc_zero
(
size
);
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
texturetype
,
&
target
,
bitmap
,
size
);
if
(
hr
==
S_OK
)
{
/* blit to target dib */
if
(
texturetype
==
DWRITE_TEXTURE_ALIASED_1x1
)
blit_8
(
&
This
->
dib
,
bitmap
,
&
target
,
color
);
else
blit_subpixel_888
(
&
This
->
dib
,
This
->
size
.
cx
,
bitmap
,
&
target
,
color
);
*
bbox_ret
=
target
;
}
heap_free
(
bitmap
);
}
IDWriteGlyphRunAnalysis_Release
(
analysis
);
return
S_OK
;
}
static
HDC
WINAPI
rendertarget_GetMemoryDC
(
IDWriteBitmapRenderTarget1
*
iface
)
...
...
@@ -148,19 +283,19 @@ static FLOAT WINAPI rendertarget_GetPixelsPerDip(IDWriteBitmapRenderTarget1 *ifa
{
struct
rendertarget
*
This
=
impl_from_IDWriteBitmapRenderTarget1
(
iface
);
TRACE
(
"(%p)
\n
"
,
This
);
return
This
->
p
ixels_per_
dip
;
return
This
->
p
p
dip
;
}
static
HRESULT
WINAPI
rendertarget_SetPixelsPerDip
(
IDWriteBitmapRenderTarget1
*
iface
,
FLOAT
p
ixels_per_
dip
)
static
HRESULT
WINAPI
rendertarget_SetPixelsPerDip
(
IDWriteBitmapRenderTarget1
*
iface
,
FLOAT
p
p
dip
)
{
struct
rendertarget
*
This
=
impl_from_IDWriteBitmapRenderTarget1
(
iface
);
TRACE
(
"(%p)->(%.2f)
\n
"
,
This
,
p
ixels_per_
dip
);
TRACE
(
"(%p)->(%.2f)
\n
"
,
This
,
p
p
dip
);
if
(
p
ixels_per_
dip
<=
0
.
0
)
if
(
p
p
dip
<=
0
.
0
)
return
E_INVALIDARG
;
This
->
p
ixels_per_dip
=
pixels_per_
dip
;
This
->
p
pdip
=
pp
dip
;
return
S_OK
;
}
...
...
@@ -241,7 +376,7 @@ static const IDWriteBitmapRenderTarget1Vtbl rendertargetvtbl = {
rendertarget_SetTextAntialiasMode
};
static
HRESULT
create_rendertarget
(
HDC
hdc
,
UINT32
width
,
UINT32
height
,
IDWriteBitmapRenderTarget
**
ret
)
static
HRESULT
create_rendertarget
(
IDWriteFactory
*
factory
,
HDC
hdc
,
UINT32
width
,
UINT32
height
,
IDWriteBitmapRenderTarget
**
ret
)
{
struct
rendertarget
*
target
;
HRESULT
hr
;
...
...
@@ -262,8 +397,10 @@ static HRESULT create_rendertarget(HDC hdc, UINT32 width, UINT32 height, IDWrite
}
target
->
m
=
identity
;
target
->
p
ixels_per_
dip
=
1
.
0
;
target
->
p
p
dip
=
1
.
0
;
target
->
antialiasmode
=
DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
;
target
->
factory
=
factory
;
IDWriteFactory_AddRef
(
factory
);
*
ret
=
(
IDWriteBitmapRenderTarget
*
)
&
target
->
IDWriteBitmapRenderTarget1_iface
;
...
...
@@ -501,7 +638,7 @@ static HRESULT WINAPI gdiinterop_CreateBitmapRenderTarget(IDWriteGdiInterop *ifa
{
struct
gdiinterop
*
This
=
impl_from_IDWriteGdiInterop
(
iface
);
TRACE
(
"(%p)->(%p %u %u %p)
\n
"
,
This
,
hdc
,
width
,
height
,
target
);
return
create_rendertarget
(
hdc
,
width
,
height
,
target
);
return
create_rendertarget
(
(
IDWriteFactory
*
)
This
->
factory
,
hdc
,
width
,
height
,
target
);
}
static
const
struct
IDWriteGdiInteropVtbl
gdiinteropvtbl
=
{
...
...
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