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 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 unsigned int lookup_index, | 692 unsigned int lookup_index, |
693 const hb_codepoint_t *glyphs, | 693 const hb_codepoint_t *glyphs, |
694 unsigned int glyphs_length, | 694 unsigned int glyphs_length, |
695 hb_bool_t zero_context) | 695 hb_bool_t zero_context) |
696 { | 696 { |
697 if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count
)) return false; | 697 if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count
)) return false; |
698 OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context); | 698 OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context); |
699 | 699 |
700 const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lo
okup_index); | 700 const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lo
okup_index); |
701 | 701 |
702 return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_i
ndex].digest); | 702 return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_i
ndex]); |
703 } | 703 } |
704 | 704 |
705 void | 705 void |
706 hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) | 706 hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) |
707 { | 707 { |
708 OT::GSUB::substitute_start (font, buffer); | 708 OT::GSUB::substitute_start (font, buffer); |
709 } | 709 } |
710 | 710 |
711 void | 711 void |
712 hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) | 712 hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 | 822 |
823 GPOSProxy (hb_face_t *face) : | 823 GPOSProxy (hb_face_t *face) : |
824 table (*hb_ot_layout_from_face (face)->gpos), | 824 table (*hb_ot_layout_from_face (face)->gpos), |
825 accels (hb_ot_layout_from_face (face)->gpos_accels) {} | 825 accels (hb_ot_layout_from_face (face)->gpos_accels) {} |
826 | 826 |
827 const OT::GPOS &table; | 827 const OT::GPOS &table; |
828 const hb_ot_layout_lookup_accelerator_t *accels; | 828 const hb_ot_layout_lookup_accelerator_t *accels; |
829 }; | 829 }; |
830 | 830 |
831 | 831 |
832 template <typename Lookup> | 832 template <typename Obj> |
833 static inline bool apply_once (OT::hb_apply_context_t *c, | 833 static inline bool |
834 » » » const Lookup &lookup) | 834 apply_forward (OT::hb_apply_context_t *c, |
| 835 » const Obj &obj, |
| 836 » const hb_ot_layout_lookup_accelerator_t &accel) |
835 { | 837 { |
836 if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) | 838 bool ret = false; |
837 return false; | 839 hb_buffer_t *buffer = c->buffer; |
838 return lookup.dispatch (c); | 840 while (buffer->idx < buffer->len) |
| 841 { |
| 842 if (accel.may_have (buffer->cur().codepoint) && |
| 843 » (buffer->cur().mask & c->lookup_mask) && |
| 844 » c->check_glyph_property (&buffer->cur(), c->lookup_props) && |
| 845 » obj.apply (c)) |
| 846 ret = true; |
| 847 else |
| 848 buffer->next_glyph (); |
| 849 } |
| 850 return ret; |
839 } | 851 } |
840 | 852 |
| 853 template <typename Obj> |
| 854 static inline bool |
| 855 apply_backward (OT::hb_apply_context_t *c, |
| 856 const Obj &obj, |
| 857 const hb_ot_layout_lookup_accelerator_t &accel) |
| 858 { |
| 859 bool ret = false; |
| 860 hb_buffer_t *buffer = c->buffer; |
| 861 do |
| 862 { |
| 863 if (accel.may_have (buffer->cur().codepoint) && |
| 864 (buffer->cur().mask & c->lookup_mask) && |
| 865 c->check_glyph_property (&buffer->cur(), c->lookup_props) && |
| 866 obj.apply (c)) |
| 867 ret = true; |
| 868 /* The reverse lookup doesn't "advance" cursor (for good reason). */ |
| 869 buffer->idx--; |
| 870 |
| 871 } |
| 872 while ((int) buffer->idx >= 0); |
| 873 return ret; |
| 874 } |
| 875 |
| 876 struct hb_apply_forward_context_t |
| 877 { |
| 878 inline const char *get_name (void) { return "APPLY_FORWARD"; } |
| 879 static const unsigned int max_debug_depth = HB_DEBUG_APPLY; |
| 880 typedef bool return_t; |
| 881 template <typename T, typename F> |
| 882 inline bool may_dispatch (const T *obj, const F *format) { return true; } |
| 883 template <typename T> |
| 884 inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel)
; } |
| 885 static return_t default_return_value (void) { return false; } |
| 886 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return true; } |
| 887 |
| 888 hb_apply_forward_context_t (OT::hb_apply_context_t *c_, |
| 889 const hb_ot_layout_lookup_accelerator_t &accel_) : |
| 890 c (c_), |
| 891 accel (accel_), |
| 892 debug_depth (0) {} |
| 893 |
| 894 OT::hb_apply_context_t *c; |
| 895 const hb_ot_layout_lookup_accelerator_t &accel; |
| 896 unsigned int debug_depth; |
| 897 }; |
| 898 |
841 template <typename Proxy> | 899 template <typename Proxy> |
842 static inline bool | 900 static inline void |
843 apply_string (OT::hb_apply_context_t *c, | 901 apply_string (OT::hb_apply_context_t *c, |
844 const typename Proxy::Lookup &lookup, | 902 const typename Proxy::Lookup &lookup, |
845 const hb_ot_layout_lookup_accelerator_t &accel) | 903 const hb_ot_layout_lookup_accelerator_t &accel) |
846 { | 904 { |
847 bool ret = false; | |
848 hb_buffer_t *buffer = c->buffer; | 905 hb_buffer_t *buffer = c->buffer; |
849 | 906 |
850 if (unlikely (!buffer->len || !c->lookup_mask)) | 907 if (unlikely (!buffer->len || !c->lookup_mask)) |
851 return false; | 908 return; |
852 | 909 |
853 c->set_lookup (lookup); | 910 c->set_lookup (lookup); |
854 | 911 |
855 if (likely (!lookup.is_reverse ())) | 912 if (likely (!lookup.is_reverse ())) |
856 { | 913 { |
857 /* in/out forward substitution/positioning */ | 914 /* in/out forward substitution/positioning */ |
858 if (Proxy::table_index == 0) | 915 if (Proxy::table_index == 0) |
859 buffer->clear_output (); | 916 buffer->clear_output (); |
860 buffer->idx = 0; | 917 buffer->idx = 0; |
861 | 918 |
862 while (buffer->idx < buffer->len) | 919 bool ret; |
| 920 if (lookup.get_subtable_count () == 1) |
863 { | 921 { |
864 if (accel.digest.may_have (buffer->cur().codepoint) && | 922 hb_apply_forward_context_t c_forward (c, accel); |
865 » (buffer->cur().mask & c->lookup_mask) && | 923 ret = lookup.dispatch (&c_forward); |
866 » apply_once (c, lookup)) | |
867 » ret = true; | |
868 else | |
869 » buffer->next_glyph (); | |
870 } | 924 } |
| 925 else |
| 926 ret = apply_forward (c, lookup, accel); |
871 if (ret) | 927 if (ret) |
872 { | 928 { |
873 if (!Proxy::inplace) | 929 if (!Proxy::inplace) |
874 buffer->swap_buffers (); | 930 buffer->swap_buffers (); |
875 else | 931 else |
876 assert (!buffer->has_separate_output ()); | 932 » assert (!buffer->has_separate_output ()); |
877 } | 933 } |
878 } | 934 } |
879 else | 935 else |
880 { | 936 { |
881 /* in-place backward substitution/positioning */ | 937 /* in-place backward substitution/positioning */ |
882 if (Proxy::table_index == 0) | 938 if (Proxy::table_index == 0) |
883 buffer->remove_output (); | 939 buffer->remove_output (); |
884 buffer->idx = buffer->len - 1; | 940 buffer->idx = buffer->len - 1; |
885 do | |
886 { | |
887 if (accel.digest.may_have (buffer->cur().codepoint) && | |
888 (buffer->cur().mask & c->lookup_mask) && | |
889 apply_once (c, lookup)) | |
890 ret = true; | |
891 /* The reverse lookup doesn't "advance" cursor (for good reason). */ | |
892 buffer->idx--; | |
893 | 941 |
894 } | 942 apply_backward (c, lookup, accel); |
895 while ((int) buffer->idx >= 0); | |
896 } | 943 } |
897 | |
898 return ret; | |
899 } | 944 } |
900 | 945 |
901 template <typename Proxy> | 946 template <typename Proxy> |
902 inline void hb_ot_map_t::apply (const Proxy &proxy, | 947 inline void hb_ot_map_t::apply (const Proxy &proxy, |
903 const hb_ot_shape_plan_t *plan, | 948 const hb_ot_shape_plan_t *plan, |
904 hb_font_t *font, | 949 hb_font_t *font, |
905 hb_buffer_t *buffer) const | 950 hb_buffer_t *buffer) const |
906 { | 951 { |
907 const unsigned int table_index = proxy.table_index; | 952 const unsigned int table_index = proxy.table_index; |
908 unsigned int i = 0; | 953 unsigned int i = 0; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 apply (proxy, plan, font, buffer); | 986 apply (proxy, plan, font, buffer); |
942 } | 987 } |
943 | 988 |
944 HB_INTERNAL void | 989 HB_INTERNAL void |
945 hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, | 990 hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, |
946 const OT::SubstLookup &lookup, | 991 const OT::SubstLookup &lookup, |
947 const hb_ot_layout_lookup_accelerator_t &accel) | 992 const hb_ot_layout_lookup_accelerator_t &accel) |
948 { | 993 { |
949 apply_string<GSUBProxy> (c, lookup, accel); | 994 apply_string<GSUBProxy> (c, lookup, accel); |
950 } | 995 } |
OLD | NEW |