2
2
// Distributed under the MIT license. See the LICENSE file in the project root for more information.
3
3
4
4
using System ;
5
+ using System . Globalization ;
5
6
using System . Runtime . CompilerServices ;
6
7
using System . Runtime . InteropServices ;
7
8
using SharpGen . Runtime ;
@@ -11,14 +12,17 @@ namespace Vortice.DirectWrite
11
12
public partial class GlyphRun : IDisposable
12
13
{
13
14
public IDWriteFontFace ? FontFace { set ; get ; }
14
- public ushort [ ] ? GlyphIndices { get ; set ; }
15
- public float [ ] ? GlyphAdvances { get ; set ; }
16
- public GlyphOffset [ ] ? GlyphOffsets { get ; set ; }
15
+ public ushort [ ] ? Indices { get ; set ; }
16
+ public float [ ] ? Advances { get ; set ; }
17
+ public GlyphOffset [ ] ? Offsets { get ; set ; }
17
18
18
19
public void Dispose ( )
19
20
{
20
- FontFace ? . Dispose ( ) ;
21
- FontFace = null ;
21
+ if ( FontFace != null )
22
+ {
23
+ FontFace . Dispose ( ) ;
24
+ FontFace = null ;
25
+ }
22
26
}
23
27
24
28
#region Marshal
@@ -53,104 +57,97 @@ internal unsafe void __MarshalFree(ref __Native @ref)
53
57
internal unsafe void __MarshalFrom ( ref __Native @ref )
54
58
{
55
59
FontFace = ( @ref . FontFace == IntPtr . Zero ) ? null : new IDWriteFontFace ( @ref . FontFace ) ;
56
- FontFace ? . AddRef ( ) ;
60
+ if ( FontFace != null )
61
+ ( ( IUnknown ) FontFace ) . AddRef ( ) ;
57
62
58
- FontEmSize = @ref . FontEmSize ;
63
+ FontSize = @ref . FontEmSize ;
64
+ GlyphCount = @ref . GlyphCount ;
59
65
GlyphCount = @ref . GlyphCount ;
60
- GlyphIndices = null ;
61
- GlyphAdvances = null ;
62
- GlyphOffsets = null ;
63
- IsSideways = @ref . IsSideways ;
64
- BidiLevel = @ref . BidiLevel ;
65
-
66
66
if ( @ref . GlyphIndices != IntPtr . Zero )
67
67
{
68
- GlyphIndices = new ushort [ @ref . GlyphCount ] ;
69
- if ( @ref . GlyphCount > 0 )
70
- fixed ( void * indicesPtr = & GlyphIndices [ 0 ] )
71
- {
72
- Unsafe . CopyBlock ( indicesPtr , @ref . GlyphIndices . ToPointer ( ) ,
73
- ( uint ) ( sizeof ( ushort ) * @ref . GlyphCount ) ) ;
74
- }
68
+ Indices = new ushort [ GlyphCount ] ;
69
+ if ( GlyphCount > 0 )
70
+ UnsafeUtilities . Read ( @ref . GlyphIndices , Indices , GlyphCount ) ;
75
71
}
76
72
77
73
if ( @ref . GlyphAdvances != IntPtr . Zero )
78
74
{
79
- GlyphAdvances = new float [ @ref . GlyphCount ] ;
80
- if ( @ref . GlyphCount > 0 )
81
- fixed ( void * advancesPtr = & GlyphAdvances [ 0 ] )
82
- {
83
- Unsafe . CopyBlock (
84
- advancesPtr ,
85
- @ref . GlyphAdvances . ToPointer ( ) ,
86
- ( uint ) ( sizeof ( float ) * @ref . GlyphCount ) ) ;
87
- }
75
+ Advances = new float [ GlyphCount ] ;
76
+ if ( GlyphCount > 0 )
77
+ UnsafeUtilities . Read ( @ref . GlyphAdvances , Advances , GlyphCount ) ;
88
78
}
89
79
90
80
if ( @ref . GlyphOffsets != IntPtr . Zero )
91
81
{
92
- GlyphOffsets = new GlyphOffset [ @ref . GlyphCount ] ;
93
- if ( @ref . GlyphCount > 0 )
94
- fixed ( void * offsetsPtr = & GlyphOffsets [ 0 ] )
95
- {
96
- Unsafe . CopyBlock ( offsetsPtr , @ref . GlyphOffsets . ToPointer ( ) , ( uint ) ( sizeof ( GlyphOffset ) * @ref . GlyphCount ) ) ;
97
- }
82
+ Offsets = new GlyphOffset [ GlyphCount ] ;
83
+ if ( GlyphCount > 0 )
84
+ UnsafeUtilities . Read ( @ref . GlyphOffsets , Offsets , GlyphCount ) ;
98
85
}
86
+
87
+ IsSideways = @ref . IsSideways ;
88
+ BidiLevel = @ref . BidiLevel ;
99
89
}
100
90
101
91
internal unsafe void __MarshalTo ( ref __Native @ref )
102
92
{
103
93
@ref . FontFace = FontFace == null ? IntPtr . Zero : FontFace . NativePointer ;
104
- @ref . FontEmSize = FontEmSize ;
105
- @ref . GlyphCount = GlyphCount ;
94
+ @ref . FontEmSize = FontSize ;
95
+ @ref . GlyphCount = - 1 ;
106
96
@ref . GlyphIndices = IntPtr . Zero ;
107
97
@ref . GlyphAdvances = IntPtr . Zero ;
108
98
@ref . GlyphOffsets = IntPtr . Zero ;
109
- @ref . IsSideways = IsSideways ;
110
- @ref . BidiLevel = BidiLevel ;
111
99
112
- if ( GlyphIndices != null )
100
+ if ( Indices != null )
113
101
{
114
- @ref . GlyphIndices = Marshal . AllocHGlobal ( GlyphIndices . Length * sizeof ( ushort ) ) ;
115
- if ( GlyphCount > 0 )
102
+ @ref . GlyphCount = Indices . Length ;
103
+
104
+ @ref . GlyphIndices = Marshal . AllocHGlobal ( Indices . Length * sizeof ( ushort ) ) ;
105
+ if ( Indices . Length > 0 )
116
106
{
117
- fixed ( void * glyphIndicesPtr = & GlyphIndices [ 0 ] )
118
- {
119
- Unsafe . CopyBlock ( @ref . GlyphIndices . ToPointer ( ) ,
120
- glyphIndicesPtr ,
121
- ( uint ) ( sizeof ( ushort ) * GlyphCount ) ) ;
122
- }
107
+ UnsafeUtilities . Write ( @ref . GlyphIndices , Indices , 0 , Indices . Length ) ;
123
108
}
124
-
125
109
}
126
110
127
- if ( GlyphAdvances != null )
111
+ if ( Advances != null )
128
112
{
129
- @ref . GlyphAdvances = Marshal . AllocHGlobal ( GlyphAdvances . Length * sizeof ( float ) ) ;
130
- if ( GlyphCount > 0 )
113
+ if ( @ref . GlyphCount >= 0 && @ref . GlyphCount != Advances . Length )
131
114
{
132
- fixed ( void * glyphAdvancesPtr = & GlyphAdvances [ 0 ] )
133
- {
134
- Unsafe . CopyBlock ( @ref . GlyphAdvances . ToPointer ( ) ,
135
- glyphAdvancesPtr ,
136
- ( uint ) ( sizeof ( float ) * GlyphCount ) ) ;
137
- }
115
+ throw new InvalidOperationException (
116
+ $ "Invalid length for array Advances [{ Advances . Length } ] and Indices [{ @ref . GlyphCount } ]. Indices, Advances and Offsets array must have same size - or may be null"
117
+ ) ;
118
+ }
119
+
120
+ @ref . GlyphCount = Advances . Length ;
121
+ @ref . GlyphAdvances = Marshal . AllocHGlobal ( Advances . Length * sizeof ( float ) ) ;
122
+ if ( Advances . Length > 0 )
123
+ {
124
+ UnsafeUtilities . Write ( @ref . GlyphAdvances , Advances , 0 , Advances . Length ) ;
138
125
}
139
126
}
140
127
141
- if ( GlyphOffsets != null )
128
+ if ( Offsets != null )
142
129
{
143
- @ref . GlyphOffsets = Marshal . AllocHGlobal ( GlyphOffsets . Length * sizeof ( GlyphOffset ) ) ;
144
- if ( GlyphCount > 0 )
130
+ if ( @ref . GlyphCount >= 0 && @ref . GlyphCount != Offsets . Length )
145
131
{
146
- fixed ( void * offsetsPtr = & GlyphOffsets [ 0 ] )
147
- {
148
- Unsafe . CopyBlock ( @ref . GlyphOffsets . ToPointer ( ) ,
149
- offsetsPtr ,
150
- ( uint ) ( sizeof ( GlyphOffset ) * GlyphCount ) ) ;
151
- }
132
+ throw new InvalidOperationException ( $ "Invalid length for array Offsets [{ Offsets . Length } ]. Indices, Advances and Offsets array must have same size (Current is [{ @ref . GlyphCount } ]- or may be null") ;
133
+ }
134
+
135
+ @ref . GlyphCount = this . Offsets . Length ;
136
+ @ref . GlyphOffsets = Marshal . AllocHGlobal ( this . Offsets . Length * sizeof ( GlyphOffset ) ) ;
137
+ if ( this . Offsets . Length > 0 )
138
+ {
139
+ UnsafeUtilities . Write ( @ref . GlyphOffsets , Offsets , 0 , this . Offsets . Length ) ;
152
140
}
153
141
}
142
+
143
+ if ( @ref . GlyphCount < 0 )
144
+ @ref . GlyphCount = 0 ;
145
+
146
+ // Update GlyphCount only for debug purpose
147
+ GlyphCount = @ref . GlyphCount ;
148
+
149
+ @ref . IsSideways = this . IsSideways ;
150
+ @ref . BidiLevel = this . BidiLevel ;
154
151
}
155
152
#endregion Marshal
156
153
}
0 commit comments