summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoazin Khatti <moazinkhatri@gmail.com>2019-07-25 16:24:33 +0500
committerMoazin Khatti <moazinkhatri@gmail.com>2019-08-26 01:17:14 +0500
commitba9e6f9d410bc1b45703a849fa9d249edf46a2e7 (patch)
tree02f8fa989ec3611fccde17db1346441e524eeb7f
parent6962986cf31dd37de81ca40ad379d4aede89b465 (diff)
downloadfreetype2-ba9e6f9d410bc1b45703a849fa9d249edf46a2e7.tar.gz
Implement binary search for SVG Document Lookup.
-rw-r--r--src/sfnt/ttsvg.c66
1 files changed, 52 insertions, 14 deletions
diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c
index eea3d2536..961b077fa 100644
--- a/src/sfnt/ttsvg.c
+++ b/src/sfnt/ttsvg.c
@@ -127,8 +127,8 @@
{
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
- FT_ULong cur_doc_offset;
- FT_ULong cur_doc_length;
+ FT_ULong offset;
+ FT_ULong length;
} Svg_doc;
Svg_doc
@@ -137,8 +137,8 @@
Svg_doc doc;
doc.start_glyph_id = FT_NEXT_USHORT( stream );
doc.end_glyph_id = FT_NEXT_USHORT( stream );
- doc.cur_doc_offset = FT_NEXT_ULONG( stream );
- doc.cur_doc_length = FT_NEXT_ULONG( stream );
+ doc.offset = FT_NEXT_ULONG( stream );
+ doc.length = FT_NEXT_ULONG( stream );
return doc;
}
@@ -165,30 +165,68 @@
{
FT_Error error;
Svg_doc cur_doc;
+ Svg_doc start_doc;
+ Svg_doc mid_doc;
+ Svg_doc end_doc;
+
+ FT_Bool found = FALSE;
+ FT_UInt i = 0;
+ FT_UInt start_index = 0;
+ FT_UInt end_index = num_entries - 1;
+ FT_Int comp_res;
- FT_Bool found = FALSE;
- FT_UInt i = 0;
/* TODO: (OT-SVG) Convert to efficient search algorithm */
- for ( i = 0; i < num_entries; i++)
+ /* search algo */
+
+ if ( num_entries == 0 )
+ {
+ error = FT_THROW( Invalid_Table );
+ return error;
+ }
+
+ start_doc = extract_svg_doc( stream + start_index * 12 );
+ end_doc = extract_svg_doc( stream + end_index * 12 );
+ if ( ( compare_svg_doc( start_doc, glyph_index ) == -1 ) ||
+ ( compare_svg_doc( end_doc, glyph_index ) == 1 ) )
{
- cur_doc = extract_svg_doc( stream );
- stream += 12;
- if ( compare_svg_doc( cur_doc, glyph_index ) == 0 )
+ error = FT_THROW( Invalid_Glyph_Index );
+ return error;
+ }
+
+ while ( start_index <= end_index )
+ {
+ i = ( start_index + end_index ) / 2;
+ mid_doc = extract_svg_doc( stream + i * 12 );
+ comp_res = compare_svg_doc( mid_doc, glyph_index );
+ if ( comp_res == 1 )
+ {
+ start_index = i + 1;
+ start_doc = extract_svg_doc( stream + start_index * 4 );
+ }
+ else if ( comp_res == -1 )
+ {
+ end_index = i - 1;
+ end_doc = extract_svg_doc( stream + end_index * 4 );
+ }
+ else
{
found = TRUE;
- *doc_offset = cur_doc.cur_doc_offset;
- *doc_length = cur_doc.cur_doc_length;
break;
}
}
+ /* search algo end */
+ /* must set `found', `doc_offset' and `doc_length'. */
+ /* also keep `cur_doc' alive */
if ( found != TRUE )
error = FT_THROW( Invalid_Glyph_Index );
else
{
- *start_glyph = cur_doc.start_glyph_id;
- *end_glyph = cur_doc.end_glyph_id;
+ *doc_offset = mid_doc.offset;
+ *doc_length = mid_doc.length;
+ *start_glyph = mid_doc.start_glyph_id;
+ *end_glyph = mid_doc.end_glyph_id;
error = FT_Err_Ok;
}
return error;