Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
redox-os
stb_truetype-rs
Commits
d0c5dd41
Commit
d0c5dd41
authored
Sep 02, 2018
by
Alex Butler
Browse files
Merge branch 'get_glyph_shape-separate-flags' into 'master'
Safe rework of get_glyph_shape Closes
#15
and
#16
See merge request
!24
parents
3e5c2799
2d3a5a85
Pipeline
#1219
passed with stages
in 4 minutes and 15 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CHANGELOG.md
View file @
d0c5dd41
## master
*
Remove all unsafe usage.
## 0.2.3
*
Add
`is_collection(&[u8]) -> bool`
.
...
...
src/lib.rs
View file @
d0c5dd41
#![allow(unknown_lints)]
#![warn(clippy)]
#![allow(
too_many_arguments,
cast_lossless,
many_single_char_names,
)]
#![allow(too_many_arguments,
cast_lossless,
many_single_char_names,)]
extern
crate
byteorder
;
...
...
@@ -645,64 +641,10 @@ impl<Data: Deref<Target = [u8]>> FontInfo<Data> {
None
=>
true
,
}
}
/// Like `get_codepoint_shape`, but takes a glyph index instead. Use this
/// if you have cached the glyph index for a codepoint.
#[allow(cyclomatic_complexity)]
// FIXME rework
pub
fn
get_glyph_shape
(
&
self
,
glyph_index
:
u32
)
->
Option
<
Vec
<
Vertex
>>
{
use
VertexType
::
*
;
fn
close_shape
(
vertices
:
&
mut
[
Vertex
],
num_vertices
:
&
mut
usize
,
was_off
:
bool
,
start_off
:
bool
,
sx
:
i32
,
sy
:
i32
,
scx
:
i32
,
scy
:
i32
,
cx
:
i32
,
cy
:
i32
,
)
{
use
VertexType
::
*
;
if
start_off
{
if
was_off
{
vertices
[
*
num_vertices
]
=
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
((
cx
+
scx
)
>>
1
)
as
i16
,
y
:
((
cy
+
scy
)
>>
1
)
as
i16
,
cx
:
cx
as
i16
,
cy
:
cy
as
i16
,
};
*
num_vertices
+=
1
;
}
vertices
[
*
num_vertices
]
=
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
sx
as
i16
,
y
:
sy
as
i16
,
cx
:
scx
as
i16
,
cy
:
scy
as
i16
,
};
}
else
{
vertices
[
*
num_vertices
]
=
if
was_off
{
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
sx
as
i16
,
y
:
sy
as
i16
,
cx
:
cx
as
i16
,
cy
:
cy
as
i16
,
}
}
else
{
Vertex
{
type_
:
LineTo
as
u8
,
x
:
sx
as
i16
,
y
:
sy
as
i16
,
cx
:
0
,
cy
:
0
,
}
};
}
*
num_vertices
+=
1
;
}
let
g
=
match
self
.get_glyf_offset
(
glyph_index
)
{
Some
(
g
)
=>
&
self
.data
[
g
as
usize
..
],
None
=>
return
None
,
...
...
@@ -710,209 +652,7 @@ impl<Data: Deref<Target = [u8]>> FontInfo<Data> {
let
number_of_contours
=
BE
::
read_i16
(
g
);
let
vertices
:
Vec
<
Vertex
>
=
if
number_of_contours
>
0
{
let
number_of_contours
=
number_of_contours
as
usize
;
let
mut
start_off
=
false
;
let
mut
was_off
=
false
;
let
end_points_of_contours
=
&
g
[
10
..
];
let
ins
=
BE
::
read_u16
(
&
g
[
10
+
number_of_contours
*
2
..
])
as
usize
;
let
mut
points
=
&
g
[
10
+
number_of_contours
*
2
+
2
+
ins
..
];
let
n
=
1
+
BE
::
read_u16
(
&
end_points_of_contours
[
number_of_contours
*
2
-
2
..
])
as
usize
;
let
m
=
n
+
2
*
number_of_contours
;
// a loose bound on how many vertices we might need
let
mut
vertices
:
Vec
<
Vertex
>
=
Vec
::
with_capacity
(
m
);
unsafe
{
vertices
.set_len
(
m
)
};
let
mut
next_move
=
0
;
let
mut
flagcount
=
0
;
// in first pass, we load uninterpreted data into the allocated array
// above, shifted to the end of the array so we won't overwrite it when
// we create our final data starting from the front
// starting offset for uninterpreted data, regardless of how m ends up being
// calculated
let
off
=
m
-
n
;
// first load flags
let
mut
flags
=
0
;
for
i
in
0
..
n
{
if
flagcount
==
0
{
flags
=
points
[
0
];
points
=
&
points
[
1
..
];
if
flags
&
8
!=
0
{
flagcount
=
points
[
0
];
points
=
&
points
[
1
..
];
}
}
else
{
flagcount
-=
1
;
}
vertices
[
off
+
i
]
.type_
=
flags
;
}
// now load x coordinates
let
mut
x
=
0i32
;
for
i
in
0
..
n
{
let
flags
=
vertices
[
off
+
i
]
.type_
;
if
flags
==
255
{
println!
(
"{:?}"
,
flags
);
}
if
flags
&
2
!=
0
{
let
dx
=
points
[
0
]
as
i32
;
points
=
&
points
[
1
..
];
if
flags
&
16
!=
0
{
// ???
x
+=
dx
;
}
else
{
x
-=
dx
;
}
}
else
if
flags
&
16
==
0
{
x
+=
points
[
0
]
as
i32
*
256
+
points
[
1
]
as
i32
;
points
=
&
points
[
2
..
];
}
vertices
[
off
+
i
]
.x
=
x
as
i16
;
}
// now load y coordinates
let
mut
y
=
0i32
;
for
i
in
0
..
n
{
let
flags
=
vertices
[
off
+
i
]
.type_
;
if
flags
&
4
!=
0
{
let
dy
=
points
[
0
]
as
i32
;
points
=
&
points
[
1
..
];
if
flags
&
32
!=
0
{
y
+=
dy
;
}
else
{
y
-=
dy
;
}
}
else
if
flags
&
32
==
0
{
y
+=
points
[
0
]
as
i32
*
256
+
points
[
1
]
as
i32
;
points
=
&
points
[
2
..
];
}
vertices
[
off
+
i
]
.y
=
y
as
i16
;
}
// now convert them to our format
let
mut
num_vertices
=
0
;
let
mut
sx
=
0
;
let
mut
sy
=
0
;
let
mut
cx
=
0
;
let
mut
cy
=
0
;
let
mut
scx
=
0
;
let
mut
scy
=
0
;
let
mut
i
=
0
;
let
mut
j
=
0
;
while
i
<
n
{
let
flags
=
vertices
[
off
+
i
]
.type_
;
x
=
vertices
[
off
+
i
]
.x
as
i32
;
y
=
vertices
[
off
+
i
]
.y
as
i32
;
if
next_move
==
i
{
if
i
!=
0
{
close_shape
(
&
mut
vertices
[
..
],
&
mut
num_vertices
,
was_off
,
start_off
,
sx
,
sy
,
scx
,
scy
,
cx
,
cy
,
);
}
// now start the new one
start_off
=
flags
&
1
==
0
;
if
start_off
{
// if we start off with an off-curve point, then when we need to find a
// point on the curve where we can start, and we
// need to save some state for
// when we wraparound.
scx
=
x
;
scy
=
y
;
if
vertices
[
off
+
i
+
1
]
.type_
as
u8
&
1
==
0
{
// next point is also a curve point, so interpolate an on-point curve
sx
=
(
x
+
vertices
[
off
+
i
+
1
]
.x
as
i32
)
>>
1
;
sy
=
(
y
+
vertices
[
off
+
i
+
1
]
.y
as
i32
)
>>
1
;
}
else
{
// otherwise just use the next point as our start point
sx
=
vertices
[
off
+
i
+
1
]
.x
as
i32
;
sy
=
vertices
[
off
+
i
+
1
]
.y
as
i32
;
i
+=
1
;
// we're using point i+1 as the starting point, so skip it
}
}
else
{
sx
=
x
;
sy
=
y
;
}
vertices
[
num_vertices
]
=
Vertex
{
type_
:
MoveTo
as
u8
,
x
:
sx
as
i16
,
y
:
sy
as
i16
,
cx
:
0
,
cy
:
0
,
};
num_vertices
+=
1
;
was_off
=
false
;
next_move
=
1
+
BE
::
read_u16
(
&
end_points_of_contours
[
j
*
2
..
])
as
usize
;
j
+=
1
;
}
else
if
flags
&
1
==
0
{
// if it's a curve
if
was_off
{
// two off-curve control points in a row means interpolate an on-curve
// midpoint
vertices
[
num_vertices
]
=
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
((
cx
+
x
)
>>
1
)
as
i16
,
y
:
((
cy
+
y
)
>>
1
)
as
i16
,
cx
:
cx
as
i16
,
cy
:
cy
as
i16
,
};
num_vertices
+=
1
;
}
cx
=
x
;
cy
=
y
;
was_off
=
true
;
}
else
{
if
was_off
{
vertices
[
num_vertices
]
=
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
x
as
i16
,
y
:
y
as
i16
,
cx
:
cx
as
i16
,
cy
:
cy
as
i16
,
}
}
else
{
vertices
[
num_vertices
]
=
Vertex
{
type_
:
LineTo
as
u8
,
x
:
x
as
i16
,
y
:
y
as
i16
,
cx
:
0
as
i16
,
cy
:
0
as
i16
,
}
}
num_vertices
+=
1
;
was_off
=
false
;
}
i
+=
1
;
}
close_shape
(
&
mut
vertices
[
..
],
&
mut
num_vertices
,
was_off
,
start_off
,
sx
,
sy
,
scx
,
scy
,
cx
,
cy
,
);
assert
!
(
num_vertices
<=
vertices
.len
());
vertices
.truncate
(
num_vertices
);
vertices
self
.glyph_shape_positive_contours
(
g
,
number_of_contours
as
usize
)
}
else
if
number_of_contours
==
-
1
{
// Compound shapes
let
mut
more
=
true
;
...
...
@@ -1003,6 +743,258 @@ impl<Data: Deref<Target = [u8]>> FontInfo<Data> {
Some
(
vertices
)
}
#[inline]
fn
glyph_shape_positive_contours
(
&
self
,
glyph_data
:
&
[
u8
],
number_of_contours
:
usize
,
)
->
Vec
<
Vertex
>
{
use
VertexType
::
*
;
struct
FlagData
{
flags
:
u8
,
x
:
i16
,
y
:
i16
,
}
#[inline]
fn
close_shape
(
vertices
:
&
mut
Vec
<
Vertex
>
,
was_off
:
bool
,
start_off
:
bool
,
sx
:
i16
,
sy
:
i16
,
scx
:
i16
,
scy
:
i16
,
cx
:
i16
,
cy
:
i16
,
)
{
if
start_off
{
if
was_off
{
vertices
.push
(
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
(
cx
+
scx
)
>>
1
,
y
:
(
cy
+
scy
)
>>
1
,
cx
,
cy
,
});
}
vertices
.push
(
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
sx
,
y
:
sy
,
cx
:
scx
,
cy
:
scy
,
});
}
else
{
vertices
.push
(
if
was_off
{
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
sx
,
y
:
sy
,
cx
,
cy
,
}
}
else
{
Vertex
{
type_
:
LineTo
as
u8
,
x
:
sx
,
y
:
sy
,
cx
:
0
,
cy
:
0
,
}
});
}
}
let
number_of_contours
=
number_of_contours
as
usize
;
let
mut
start_off
=
false
;
let
mut
was_off
=
false
;
let
end_points_of_contours
=
&
glyph_data
[
10
..
];
let
ins
=
BE
::
read_u16
(
&
glyph_data
[
10
+
number_of_contours
*
2
..
])
as
usize
;
let
mut
points
=
&
glyph_data
[
10
+
number_of_contours
*
2
+
2
+
ins
..
];
let
n
=
1
+
BE
::
read_u16
(
&
end_points_of_contours
[
number_of_contours
*
2
-
2
..
])
as
usize
;
let
m
=
n
+
2
*
number_of_contours
;
// a loose bound on how many vertices we might need
let
mut
vertices
:
Vec
<
Vertex
>
=
Vec
::
with_capacity
(
m
);
let
mut
flag_data
=
Vec
::
with_capacity
(
n
);
let
mut
next_move
=
0
;
// in first pass, we load uninterpreted data into the allocated array above
// first load flags
{
let
mut
flagcount
=
0
;
let
mut
flags
=
0
;
for
_
in
0
..
n
{
if
flagcount
==
0
{
flags
=
points
[
0
];
if
flags
&
8
!=
0
{
flagcount
=
points
[
1
];
points
=
&
points
[
2
..
];
}
else
{
points
=
&
points
[
1
..
];
}
}
else
{
flagcount
-=
1
;
}
flag_data
.push
(
FlagData
{
flags
,
x
:
0
,
y
:
0
});
}
}
// now load x coordinates
let
mut
x_coord
=
0_i16
;
for
flag_data
in
&
mut
flag_data
{
let
flags
=
flag_data
.flags
;
if
flags
&
2
!=
0
{
let
dx
=
i16
::
from
(
points
[
0
]);
points
=
&
points
[
1
..
];
if
flags
&
16
!=
0
{
// ???
x_coord
+=
dx
;
}
else
{
x_coord
-=
dx
;
}
}
else
if
flags
&
16
==
0
{
x_coord
+=
BE
::
read_i16
(
points
);
points
=
&
points
[
2
..
];
}
flag_data
.x
=
x_coord
;
}
// now load y coordinates
let
mut
y_coord
=
0_i16
;
for
flag_data
in
&
mut
flag_data
{
let
flags
=
flag_data
.flags
;
if
flags
&
4
!=
0
{
let
dy
=
i16
::
from
(
points
[
0
]);
points
=
&
points
[
1
..
];
if
flags
&
32
!=
0
{
y_coord
+=
dy
;
}
else
{
y_coord
-=
dy
;
}
}
else
if
flags
&
32
==
0
{
y_coord
+=
BE
::
read_i16
(
points
);
points
=
&
points
[
2
..
];
}
flag_data
.y
=
y_coord
;
}
// now convert them to our format
let
mut
sx
=
0
;
let
mut
sy
=
0
;
let
mut
cx
=
0
;
let
mut
cy
=
0
;
let
mut
scx
=
0
;
let
mut
scy
=
0
;
let
mut
j
=
0
;
let
mut
iter
=
flag_data
.into_iter
()
.enumerate
()
.peekable
();
while
let
Some
((
index
,
FlagData
{
flags
,
x
,
y
}))
=
iter
.next
()
{
if
next_move
==
index
{
if
index
!=
0
{
close_shape
(
&
mut
vertices
,
was_off
,
start_off
,
sx
,
sy
,
scx
,
scy
,
cx
,
cy
);
}
// now start the new one
start_off
=
flags
&
1
==
0
;
if
start_off
{
// if we start off with an off-curve point, then when we need to find a
// point on the curve where we can start, and we
// need to save some state for
// when we wraparound.
scx
=
x
;
scy
=
y
;
let
(
next_flags
,
next_x
,
next_y
)
=
{
let
peek
=
&
iter
.peek
()
.unwrap
()
.1
;
(
peek
.flags
,
peek
.x
,
peek
.y
)
};
if
next_flags
&
1
==
0
{
// next point is also a curve point, so interpolate an on-point curve
sx
=
(
x
+
next_x
)
>>
1
;
sy
=
(
y
+
next_y
)
>>
1
;
}
else
{
// otherwise just use the next point as our start point
sx
=
next_x
;
sy
=
next_y
;
// we're using point i+1 as the starting point, so skip it
let
_
=
iter
.next
();
}
}
else
{
sx
=
x
;
sy
=
y
;
}
vertices
.push
(
Vertex
{
type_
:
MoveTo
as
u8
,
x
:
sx
,
y
:
sy
,
cx
:
0
,
cy
:
0
,
});
was_off
=
false
;
next_move
=
1
+
BE
::
read_u16
(
&
end_points_of_contours
[
j
*
2
..
])
as
usize
;
j
+=
1
;
}
else
if
flags
&
1
==
0
{
// if it's a curve
if
was_off
{
// two off-curve control points in a row means interpolate an on-curve
// midpoint
vertices
.push
(
Vertex
{
type_
:
CurveTo
as
u8
,
x
:
((
cx
+
x
)
>>
1
),
y
:
((
cy
+
y
)
>>
1
),
cx
,
cy
,
});
}
cx
=
x
;
cy
=
y
;
was_off
=
true
;
}
else
{
vertices
.push
(
if
was_off
{
Vertex
{
type_
:
CurveTo
as
u8
,
x
,
y
,
cx
,
cy
,
}
}
else
{
Vertex
{
type_
:
LineTo
as
u8
,
x
,
y
,
cx
:
0
,
cy
:
0
,
}
});
was_off
=
false
;
}
}
close_shape
(
&
mut
vertices
,
// &mut num_vertices,
was_off
,
start_off
,
sx
,
sy
,
scx
,
scy
,
cx
,
cy
,
);
vertices
}
/// like `get_codepoint_h_metrics`, but takes a glyph index instead. Use
/// this if you have cached the glyph index for a codepoint.
pub
fn
get_glyph_h_metrics
(
&
self
,
glyph_index
:
u32
)
->
HMetrics
{
...
...
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