Skip to content

Commit

Permalink
add face unicode-set() and unicode-to-gid-map()
Browse files Browse the repository at this point in the history
Along with new HarfBUzz::Set and HafrBuzz::Map classes
  • Loading branch information
dwarring committed Jan 12, 2024
1 parent 3bfbc3a commit 919b155
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 1 deletion.
2 changes: 2 additions & 0 deletions META6.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
"HarfBuzz::Feature": "lib/HarfBuzz/Feature.rakumod",
"HarfBuzz::Font": "lib/HarfBuzz/Font.rakumod",
"HarfBuzz::Glyph": "lib/HarfBuzz/Glyph.rakumod",
"HarfBuzz::Map": "lib/HarfBuzz/Map.rakumod",
"HarfBuzz::Raw": "lib/HarfBuzz/Raw.rakumod",
"HarfBuzz::Raw::Defs": "lib/HarfBuzz/Raw/Defs.rakumod",
"HarfBuzz::Set": "lib/HarfBuzz/Set.rakumod",
"HarfBuzz::Shaper": "lib/HarfBuzz/Shaper.rakumod"
},
"raku": "6",
Expand Down
20 changes: 19 additions & 1 deletion lib/HarfBuzz/Face.rakumod
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
unit class HarfBuzz::Face;

use HarfBuzz::Raw;
use HarfBuzz::Raw::Defs :types, :hb-set-value;
use HarfBuzz::Blob;
use HarfBuzz::Map;
use HarfBuzz::Set;
use NativeCall;

has HarfBuzz::Blob $!blob handles<Blob>;
has hb_face $.raw is built handles<get-glyph-count> ;
has hb_face $.raw is built handles<get-glyph-count get-units-per-EM> ;

multi submethod TWEAK(hb_face:D :$!raw) is default {
$!raw.reference;
Expand All @@ -27,6 +31,20 @@ method !to-blob(HarfBuzz::Blob() $!blob) {
$!raw.reference;
}

method units-per-EM { $!raw.get-upem }

method unicode-set(::?CLASS:D:) {
my HarfBuzz::Set $set .= new;
$!raw.collect-unicode-set($set.raw);
$set;
}

method unicode-to-gid-map(::?CLASS:D:) {
my HarfBuzz::Map $map .= new;
$!raw.collect-unicode-map($map.raw, hb_set);
$map;
}

multi method COERCE(hb_face:D $raw) { self.new: :$raw; }
multi method COERCE(Str:D $file) { self.new: :$file; }
multi method COERCE(Blob:D $buf) { self.new: :$buf; }
Expand Down
32 changes: 32 additions & 0 deletions lib/HarfBuzz/Map.rakumod
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
unit class HarfBuzz::Map;

use HarfBuzz::Set;
use HarfBuzz::Raw;
use HarfBuzz::Raw::Defs :types;

has hb_map:D $!raw handles<elems> = hb_map::create();
method raw { $!raw }

method keys {
given HarfBuzz::Set.new {
$!raw.keys(.raw);
$_;
}
}

method values {
given HarfBuzz::Set.new {
$!raw.values(.raw);
$_;
}
}

method exists(UInt:D $i --> Int) {
$!raw.exists($i).so;
}

method AT-POS(UInt:D $i --> Int) {
$i < $.elems ?? $!raw.get($i) !! Int
}

submethod DESTROY { .destroy with $!raw }
19 changes: 19 additions & 0 deletions lib/HarfBuzz/Raw.rakumod
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,28 @@ class hb_buffer is repr('CPointer') is export {

#| HarfBuzz generalized set representation
class hb_set is repr('CPointer') is export {
our sub create(--> hb_set) is native($HB) is symbol('hb_set_create') {*}
method elems(--> uint32) is native($HB) is symbol('hb_set_get_population') {*}
method add(hb_codepoint) is native($HB) is symbol('hb_set_add') {*}
method del(hb_codepoint) is native($HB) is symbol('hb_set_del') {*}
method add-range (hb_codepoint, hb_codepoint) is native($HB) is symbol('hb_set_add_range') {*}
method min(--> hb_codepoint) is native($HB) is symbol('hb_set_min') {*}
method max(--> hb_codepoint) is native($HB) is symbol('hb_set_max') {*}
method next(hb_codepoint $ is rw --> hb_bool) is native($HB) is symbol('hb_set_next') {*}
method prev(hb_codepoint $ is rw --> hb_bool) is native($HB) is symbol('hb_set_previous') {*}
method next-many(hb_codepoint, CArray[hb_codepoint], uint32 --> uint32) is native($HB) is symbol('hb_set_next_many') {*}
method exists(hb_codepoint --> hb_bool) is native($HB) is symbol('hb_set_has') {*}
method destroy() is native($HB) is symbol('hb_set_destroy') {*}
}

class hb_map is repr('CPointer') is export {
our sub create(--> hb_map) is native($HB) is symbol('hb_map_create') {*}
method get(hb_codepoint --> hb_codepoint) is native($HB) is symbol('hb_map_get') {*}
method keys(hb_set) is native($HB) is symbol('hb_map_keys') {*}
method values(hb_set) is native($HB) is symbol('hb_map_values') {*}
method elems(--> uint32) is native($HB) is symbol('hb_map_get_population') {*}
method exists(hb_codepoint --> hb_bool) is native($HB) is symbol('hb_map_has') {*}
method destroy() is native($HB) is symbol('hb_map_destroy') {*}
}

#| HarfBuzz representation of a font feature
Expand Down Expand Up @@ -195,6 +210,10 @@ class hb_face is repr('CPointer') is export {
method reference(--> hb_face) is native($HB) is symbol('hb_face_reference') {*}
method reference-blob(--> hb_blob) is native($HB) is symbol('hb_face_reference_blob') {*}
method get-glyph-count(--> uint32) is native($HB) is symbol('hb_face_get_glyph_count') {*}
method collect-unicode-set(hb_set) is native($HB) is symbol('hb_face_collect_unicodes') {*}
method collect-unicode-map(hb_map, hb_set) is native($HB) is symbol('hb_face_collect_nominal_glyph_mapping') {*}
method get-table-tags(uint32, uint32 is rw, Pointer[hb_tag] is rw --> uint32) is symbol('hb_face_collect_unicodes') is native($HB) is symbol('hb_face_get_table_tags') {*}
method get-upem(--> uint32) is native($HB) is symbol('hb_face_get_upem') {*}
method destroy() is native($HB) is symbol('hb_face_destroy') {*}
}

Expand Down
26 changes: 26 additions & 0 deletions lib/HarfBuzz/Set.rakumod
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
unit class HarfBuzz::Set;

use HarfBuzz::Raw;
use HarfBuzz::Raw::Defs :types, :hb-set-value;
use NativeCall;

has hb_set:D $!raw handles<elems> = hb_set::create();
method raw { $!raw }

method exists(UInt:D $i --> Int) {
$!raw.exists($i).so;
}

method AT-POS(UInt:D $i --> Int) {
$i < $.elems ?? $!raw.get($i) !! Int
}

method array handles<Array List> {
my hb_codepoint @to-unicode;
@to-unicode[$!raw.elems - 1 ] = 0 if $!raw.elems;
my $buf = nativecast(CArray, @to-unicode);
$!raw.next-many(HB_SET_VALUE_INVALID, $buf, $!raw.elems);
@to-unicode;
}

submethod DESTROY { .destroy with $!raw }
30 changes: 30 additions & 0 deletions t/face.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use Test;
plan 4;
use HarfBuzz::Face;

my $file = 't/fonts/NimbusRoman-Regular.otf';
my HarfBuzz::Face:D() $face = %( :$file );

is $face.get-glyph-count, 855;
is $face.units-per-EM, 1000;

subtest 'unicode-set', {
my HarfBuzz::Set $unicode-set = $face.unicode-set;
ok $unicode-set.defined;
is $unicode-set.elems, 854, 'set elems';
ok $unicode-set.exists(42), 'exists';
my @unicodes := $unicode-set.array;
is @unicodes.elems, 854, 'array elems';
is @unicodes[10], 42;
}

subtest 'unicode-to-gid-map', {
my HarfBuzz::Map $unicode-map = $face.unicode-to-gid-map;
ok $unicode-map.exists(42), 'exists';
my HarfBuzz::Set $keys = $unicode-map.keys;
my HarfBuzz::Set $values = $unicode-map.values;
is $values.array[10], 11, 'values';
is $unicode-map.elems, 854, 'elems';
is $unicode-map[42], 11;
}

0 comments on commit 919b155

Please sign in to comment.