OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 1998-2004 David Turner and Werner Lemberg | 2 * Copyright © 1998-2004 David Turner and Werner Lemberg |
3 * Copyright © 2006 Behdad Esfahbod | 3 * Copyright © 2006 Behdad Esfahbod |
4 * Copyright © 2007,2008,2009 Red Hat, Inc. | 4 * Copyright © 2007,2008,2009 Red Hat, Inc. |
5 * Copyright © 2012,2013 Google, Inc. | 5 * Copyright © 2012,2013 Google, Inc. |
6 * | 6 * |
7 * This is part of HarfBuzz, a text shaping library. | 7 * This is part of HarfBuzz, a text shaping library. |
8 * | 8 * |
9 * Permission is hereby granted, without written agreement and without | 9 * Permission is hereby granted, without written agreement and without |
10 * license or royalty fees, to use, copy, modify, and distribute this | 10 * license or royalty fees, to use, copy, modify, and distribute this |
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 | 764 |
765 return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_i
ndex]); | 765 return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_i
ndex]); |
766 } | 766 } |
767 | 767 |
768 void | 768 void |
769 hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) | 769 hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) |
770 { | 770 { |
771 OT::GSUB::substitute_start (font, buffer); | 771 OT::GSUB::substitute_start (font, buffer); |
772 } | 772 } |
773 | 773 |
774 void | |
775 hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) | |
776 { | |
777 OT::GSUB::substitute_finish (font, buffer); | |
778 } | |
779 | |
780 /** | 774 /** |
781 * hb_ot_layout_lookup_substitute_closure: | 775 * hb_ot_layout_lookup_substitute_closure: |
782 * | 776 * |
783 * Since: 0.9.7 | 777 * Since: 0.9.7 |
784 **/ | 778 **/ |
785 void | 779 void |
786 hb_ot_layout_lookup_substitute_closure (hb_face_t *face, | 780 hb_ot_layout_lookup_substitute_closure (hb_face_t *face, |
787 unsigned int lookup_index, | 781 unsigned int lookup_index, |
788 hb_set_t *glyphs) | 782 hb_set_t *glyphs) |
789 { | 783 { |
(...skipping 14 matching lines...) Expand all Loading... |
804 return &_get_gpos (face) != &OT::Null(OT::GPOS); | 798 return &_get_gpos (face) != &OT::Null(OT::GPOS); |
805 } | 799 } |
806 | 800 |
807 void | 801 void |
808 hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) | 802 hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) |
809 { | 803 { |
810 OT::GPOS::position_start (font, buffer); | 804 OT::GPOS::position_start (font, buffer); |
811 } | 805 } |
812 | 806 |
813 void | 807 void |
814 hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) | 808 hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer) |
815 { | 809 { |
816 OT::GPOS::position_finish (font, buffer); | 810 OT::GPOS::position_finish_advances (font, buffer); |
| 811 } |
| 812 |
| 813 void |
| 814 hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) |
| 815 { |
| 816 OT::GPOS::position_finish_offsets (font, buffer); |
817 } | 817 } |
818 | 818 |
819 /** | 819 /** |
820 * hb_ot_layout_get_size_params: | 820 * hb_ot_layout_get_size_params: |
821 * | 821 * |
822 * Since: 0.9.10 | 822 * Since: 0.9.10 |
823 **/ | 823 **/ |
824 hb_bool_t | 824 hb_bool_t |
825 hb_ot_layout_get_size_params (hb_face_t *face, | 825 hb_ot_layout_get_size_params (hb_face_t *face, |
826 unsigned int *design_size, /* OUT. May be N
ULL */ | 826 unsigned int *design_size, /* OUT. May be N
ULL */ |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 | 895 |
896 GPOSProxy (hb_face_t *face) : | 896 GPOSProxy (hb_face_t *face) : |
897 table (*hb_ot_layout_from_face (face)->gpos), | 897 table (*hb_ot_layout_from_face (face)->gpos), |
898 accels (hb_ot_layout_from_face (face)->gpos_accels) {} | 898 accels (hb_ot_layout_from_face (face)->gpos_accels) {} |
899 | 899 |
900 const OT::GPOS &table; | 900 const OT::GPOS &table; |
901 const hb_ot_layout_lookup_accelerator_t *accels; | 901 const hb_ot_layout_lookup_accelerator_t *accels; |
902 }; | 902 }; |
903 | 903 |
904 | 904 |
905 template <typename Obj> | 905 struct hb_get_subtables_context_t : |
| 906 OT::hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG
_APPLY> |
| 907 { |
| 908 template <typename Type> |
| 909 static inline bool apply_to (const void *obj, OT::hb_apply_context_t *c) |
| 910 { |
| 911 const Type *typed_obj = (const Type *) obj; |
| 912 return typed_obj->apply (c); |
| 913 } |
| 914 |
| 915 typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_apply_context_t *c); |
| 916 |
| 917 struct hb_applicable_t |
| 918 { |
| 919 inline void init (const void *obj_, hb_apply_func_t apply_func_) |
| 920 { |
| 921 obj = obj_; |
| 922 apply_func = apply_func_; |
| 923 } |
| 924 |
| 925 inline bool apply (OT::hb_apply_context_t *c) const { return apply_func (obj
, c); } |
| 926 |
| 927 private: |
| 928 const void *obj; |
| 929 hb_apply_func_t apply_func; |
| 930 }; |
| 931 |
| 932 typedef hb_auto_array_t<hb_applicable_t> array_t; |
| 933 |
| 934 /* Dispatch interface. */ |
| 935 inline const char *get_name (void) { return "GET_SUBTABLES"; } |
| 936 template <typename T> |
| 937 inline return_t dispatch (const T &obj) |
| 938 { |
| 939 hb_applicable_t *entry = array.push(); |
| 940 if (likely (entry)) |
| 941 entry->init (&obj, apply_to<T>); |
| 942 return HB_VOID; |
| 943 } |
| 944 static return_t default_return_value (void) { return HB_VOID; } |
| 945 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } |
| 946 |
| 947 hb_get_subtables_context_t (array_t &array_) : |
| 948 » » » array (array_), |
| 949 » » » debug_depth (0) {} |
| 950 |
| 951 array_t &array; |
| 952 unsigned int debug_depth; |
| 953 }; |
| 954 |
906 static inline bool | 955 static inline bool |
907 apply_forward (OT::hb_apply_context_t *c, | 956 apply_forward (OT::hb_apply_context_t *c, |
908 » const Obj &obj, | 957 » const hb_ot_layout_lookup_accelerator_t &accel, |
909 » const hb_ot_layout_lookup_accelerator_t &accel) | 958 » const hb_get_subtables_context_t::array_t &subtables) |
910 { | 959 { |
911 bool ret = false; | 960 bool ret = false; |
912 hb_buffer_t *buffer = c->buffer; | 961 hb_buffer_t *buffer = c->buffer; |
913 while (buffer->idx < buffer->len && !buffer->in_error) | 962 while (buffer->idx < buffer->len && !buffer->in_error) |
914 { | 963 { |
| 964 bool applied = false; |
915 if (accel.may_have (buffer->cur().codepoint) && | 965 if (accel.may_have (buffer->cur().codepoint) && |
916 (buffer->cur().mask & c->lookup_mask) && | 966 (buffer->cur().mask & c->lookup_mask) && |
917 » c->check_glyph_property (&buffer->cur(), c->lookup_props) && | 967 » c->check_glyph_property (&buffer->cur(), c->lookup_props)) |
918 » obj.apply (c)) | 968 { |
| 969 for (unsigned int i = 0; i < subtables.len; i++) |
| 970 if (subtables[i].apply (c)) |
| 971 » { |
| 972 » applied = true; |
| 973 » break; |
| 974 » } |
| 975 } |
| 976 |
| 977 if (applied) |
919 ret = true; | 978 ret = true; |
920 else | 979 else |
921 buffer->next_glyph (); | 980 buffer->next_glyph (); |
922 } | 981 } |
923 return ret; | 982 return ret; |
924 } | 983 } |
925 | 984 |
926 template <typename Obj> | |
927 static inline bool | 985 static inline bool |
928 apply_backward (OT::hb_apply_context_t *c, | 986 apply_backward (OT::hb_apply_context_t *c, |
929 » » const Obj &obj, | 987 » const hb_ot_layout_lookup_accelerator_t &accel, |
930 » » const hb_ot_layout_lookup_accelerator_t &accel) | 988 » const hb_get_subtables_context_t::array_t &subtables) |
931 { | 989 { |
932 bool ret = false; | 990 bool ret = false; |
933 hb_buffer_t *buffer = c->buffer; | 991 hb_buffer_t *buffer = c->buffer; |
934 do | 992 do |
935 { | 993 { |
936 if (accel.may_have (buffer->cur().codepoint) && | 994 if (accel.may_have (buffer->cur().codepoint) && |
937 (buffer->cur().mask & c->lookup_mask) && | 995 (buffer->cur().mask & c->lookup_mask) && |
938 » c->check_glyph_property (&buffer->cur(), c->lookup_props) && | 996 » c->check_glyph_property (&buffer->cur(), c->lookup_props)) |
939 » obj.apply (c)) | 997 { |
940 ret = true; | 998 for (unsigned int i = 0; i < subtables.len; i++) |
| 999 if (subtables[i].apply (c)) |
| 1000 { |
| 1001 » ret = true; |
| 1002 » break; |
| 1003 } |
| 1004 } |
941 /* The reverse lookup doesn't "advance" cursor (for good reason). */ | 1005 /* The reverse lookup doesn't "advance" cursor (for good reason). */ |
942 buffer->idx--; | 1006 buffer->idx--; |
943 | 1007 |
944 } | 1008 } |
945 while ((int) buffer->idx >= 0); | 1009 while ((int) buffer->idx >= 0); |
946 return ret; | 1010 return ret; |
947 } | 1011 } |
948 | 1012 |
949 struct hb_apply_forward_context_t : | |
950 OT::hb_dispatch_context_t<hb_apply_forward_context_t, bool, HB_DEBUG_APPL
Y> | |
951 { | |
952 inline const char *get_name (void) { return "APPLY_FWD"; } | |
953 template <typename T> | |
954 inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel)
; } | |
955 static return_t default_return_value (void) { return false; } | |
956 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return true; } | |
957 | |
958 hb_apply_forward_context_t (OT::hb_apply_context_t *c_, | |
959 const hb_ot_layout_lookup_accelerator_t &accel_) : | |
960 c (c_), | |
961 accel (accel_), | |
962 debug_depth (0) {} | |
963 | |
964 OT::hb_apply_context_t *c; | |
965 const hb_ot_layout_lookup_accelerator_t &accel; | |
966 unsigned int debug_depth; | |
967 }; | |
968 | |
969 template <typename Proxy> | 1013 template <typename Proxy> |
970 static inline void | 1014 static inline void |
971 apply_string (OT::hb_apply_context_t *c, | 1015 apply_string (OT::hb_apply_context_t *c, |
972 const typename Proxy::Lookup &lookup, | 1016 const typename Proxy::Lookup &lookup, |
973 const hb_ot_layout_lookup_accelerator_t &accel) | 1017 const hb_ot_layout_lookup_accelerator_t &accel) |
974 { | 1018 { |
975 hb_buffer_t *buffer = c->buffer; | 1019 hb_buffer_t *buffer = c->buffer; |
976 | 1020 |
977 if (unlikely (!buffer->len || !c->lookup_mask)) | 1021 if (unlikely (!buffer->len || !c->lookup_mask)) |
978 return; | 1022 return; |
979 | 1023 |
980 c->set_lookup_props (lookup.get_props ()); | 1024 c->set_lookup_props (lookup.get_props ()); |
981 | 1025 |
| 1026 hb_get_subtables_context_t::array_t subtables; |
| 1027 hb_get_subtables_context_t c_get_subtables (subtables); |
| 1028 lookup.dispatch (&c_get_subtables); |
| 1029 |
982 if (likely (!lookup.is_reverse ())) | 1030 if (likely (!lookup.is_reverse ())) |
983 { | 1031 { |
984 /* in/out forward substitution/positioning */ | 1032 /* in/out forward substitution/positioning */ |
985 if (Proxy::table_index == 0) | 1033 if (Proxy::table_index == 0) |
986 buffer->clear_output (); | 1034 buffer->clear_output (); |
987 buffer->idx = 0; | 1035 buffer->idx = 0; |
988 | 1036 |
989 bool ret; | 1037 bool ret; |
990 if (lookup.get_subtable_count () == 1) | 1038 ret = apply_forward (c, accel, subtables); |
991 { | |
992 hb_apply_forward_context_t c_forward (c, accel); | |
993 ret = lookup.dispatch (&c_forward); | |
994 } | |
995 else | |
996 ret = apply_forward (c, lookup, accel); | |
997 if (ret) | 1039 if (ret) |
998 { | 1040 { |
999 if (!Proxy::inplace) | 1041 if (!Proxy::inplace) |
1000 buffer->swap_buffers (); | 1042 buffer->swap_buffers (); |
1001 else | 1043 else |
1002 assert (!buffer->has_separate_output ()); | 1044 assert (!buffer->has_separate_output ()); |
1003 } | 1045 } |
1004 } | 1046 } |
1005 else | 1047 else |
1006 { | 1048 { |
1007 /* in-place backward substitution/positioning */ | 1049 /* in-place backward substitution/positioning */ |
1008 if (Proxy::table_index == 0) | 1050 if (Proxy::table_index == 0) |
1009 buffer->remove_output (); | 1051 buffer->remove_output (); |
1010 buffer->idx = buffer->len - 1; | 1052 buffer->idx = buffer->len - 1; |
1011 | 1053 |
1012 apply_backward (c, lookup, accel); | 1054 apply_backward (c, accel, subtables); |
1013 } | 1055 } |
1014 } | 1056 } |
1015 | 1057 |
1016 template <typename Proxy> | 1058 template <typename Proxy> |
1017 inline void hb_ot_map_t::apply (const Proxy &proxy, | 1059 inline void hb_ot_map_t::apply (const Proxy &proxy, |
1018 const hb_ot_shape_plan_t *plan, | 1060 const hb_ot_shape_plan_t *plan, |
1019 hb_font_t *font, | 1061 hb_font_t *font, |
1020 hb_buffer_t *buffer) const | 1062 hb_buffer_t *buffer) const |
1021 { | 1063 { |
1022 const unsigned int table_index = proxy.table_index; | 1064 const unsigned int table_index = proxy.table_index; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1059 apply (proxy, plan, font, buffer); | 1101 apply (proxy, plan, font, buffer); |
1060 } | 1102 } |
1061 | 1103 |
1062 HB_INTERNAL void | 1104 HB_INTERNAL void |
1063 hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, | 1105 hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, |
1064 const OT::SubstLookup &lookup, | 1106 const OT::SubstLookup &lookup, |
1065 const hb_ot_layout_lookup_accelerator_t &accel) | 1107 const hb_ot_layout_lookup_accelerator_t &accel) |
1066 { | 1108 { |
1067 apply_string<GSUBProxy> (c, lookup, accel); | 1109 apply_string<GSUBProxy> (c, lookup, accel); |
1068 } | 1110 } |
OLD | NEW |