hb-ot-layout.cc revision 9ea7368fce3fa373d8d2925961ad211f5cf6ce70
14a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org/*
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org * Copyright (C) 1998-2004  David Turner and Werner Lemberg
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org * Copyright (C) 2006  Behdad Esfahbod
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Copyright (C) 2007,2008,2009  Red Hat, Inc.
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org *
6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org *  This is part of HarfBuzz, a text shaping library.
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org *
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * Permission is hereby granted, without written agreement and without
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * license or royalty fees, to use, copy, modify, and distribute this
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * software and its documentation for any purpose, provided that the
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * above copyright notice and the following two paragraphs appear in
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * all copies of this software.
134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org *
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
154b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * DAMAGE.
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org *
20e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
214b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
23196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
24196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org *
268ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org * Red Hat Author(s): Behdad Esfahbod
27196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org */
28196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
294b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#define HB_OT_LAYOUT_CC
304b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
319bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#include "hb-ot-layout-private.hh"
32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "hb-ot-layout-gdef-private.hh"
34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "hb-ot-layout-gsub-private.hh"
35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "hb-ot-layout-gpos-private.hh"
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
38196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include <stdlib.h>
39196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include <string.h>
4031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
4131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.agerHB_BEGIN_DECLS
4271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
4371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org
4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenhb_ot_layout_t *
45e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org_hb_ot_layout_new (hb_face_t *face)
46e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org{
475aed4fc58b91cbb1ed563e2e07b74490ba953037ulan@chromium.org  /* Remove this object altogether */
488496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
498496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
508496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_get_table (face, HB_OT_TAG_GDEF));
518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  layout->gdef = Sanitizer<GDEF>::lock_instance (layout->gdef_blob);
528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  layout->gsub_blob = Sanitizer<GSUB>::sanitize (hb_face_get_table (face, HB_OT_TAG_GSUB));
548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  layout->gsub = Sanitizer<GSUB>::lock_instance (layout->gsub_blob);
558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org
568496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_get_table (face, HB_OT_TAG_GPOS));
57e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  layout->gpos = Sanitizer<GPOS>::lock_instance (layout->gpos_blob);
58e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
59e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return layout;
60e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
61e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
62e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgvoid
6374dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org_hb_ot_layout_free (hb_ot_layout_t *layout)
6474dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org{
6574dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  hb_blob_unlock (layout->gdef_blob);
6674dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  hb_blob_unlock (layout->gsub_blob);
6774dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  hb_blob_unlock (layout->gpos_blob);
6874dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org
6974dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  hb_blob_destroy (layout->gdef_blob);
7074dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  hb_blob_destroy (layout->gsub_blob);
7174dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  hb_blob_destroy (layout->gpos_blob);
7274dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org
7374dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  free (layout->new_gdef.klasses);
7474dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org
7574dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org  free (layout);
7674dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org}
7774dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org
78303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgstatic const GDEF&
7974dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org_get_gdef (hb_face_t *face)
8074dd215b1e842a92a4731fb20f999fc0d5004a94machenbach@chromium.org{
8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return likely (face->ot_layout && face->ot_layout->gdef) ? *face->ot_layout->gdef : Null(GDEF);
8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const GSUB&
859faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org_get_gsub (hb_face_t *face)
869faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org{
879faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  return likely (face->ot_layout && face->ot_layout->gsub) ? *face->ot_layout->gsub : Null(GSUB);
889faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org}
899faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org
909faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.orgstatic const GPOS&
919faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org_get_gpos (hb_face_t *face)
929faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org{
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return likely (face->ot_layout && face->ot_layout->gpos) ? *face->ot_layout->gpos : Null(GPOS);
9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
9708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org/*
989f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org * GDEF
999f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org */
1009f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org
1019f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org/* TODO the public class_t is a mess */
1029f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org
1039f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.orghb_bool_t
1049f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.orghb_ot_layout_has_glyph_classes (hb_face_t *face)
1059f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org{
1069f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org  return _get_gdef (face).has_glyph_classes ();
1073484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org}
1083484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenhb_bool_t
110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com_hb_ot_layout_has_new_glyph_classes (hb_face_t *face)
111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com{
112c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  return face->ot_layout->new_gdef.len > 0;
1138432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org}
114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
11546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgstatic unsigned int
116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com_hb_ot_layout_get_glyph_property (hb_face_t      *face,
11746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org				  hb_codepoint_t  glyph)
118f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org{
119f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  hb_ot_layout_class_t klass;
120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  const GDEF &gdef = _get_gdef (face);
12146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
12267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  klass = gdef.get_glyph_class (glyph);
1233d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
12467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org  if (!klass && glyph < face->ot_layout->new_gdef.len)
125c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    klass = face->ot_layout->new_gdef.klasses[glyph];
12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1272abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  switch (klass) {
128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  default:
12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  case GDEF::UnclassifiedGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  case GDEF::BaseGlyph:		return HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  case GDEF::LigatureGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE;
1328ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  case GDEF::ComponentGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT;
1338ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  case GDEF::MarkGlyph:
1348ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org	klass = gdef.get_mark_attachment_type (glyph);
1358ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org	return HB_OT_LAYOUT_GLYPH_CLASS_MARK + (klass << 8);
1368ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  }
1378ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org}
1388ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org
1398ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orghb_bool_t
1408ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org_hb_ot_layout_check_glyph_property (hb_face_t    *face,
1418ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org				    hb_internal_glyph_info_t *ginfo,
1428ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org				    unsigned int  lookup_flags,
1438ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org				    unsigned int *property_out)
1448ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org{
1458ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  unsigned int property;
1468ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org
1471845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
1488ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    ginfo->gproperty = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
1498ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  property = ginfo->gproperty;
1508ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  if (property_out)
1518ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    *property_out = property;
1528ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org
1538ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  /* Not covered, if, for example, glyph class is ligature and
1548ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org   * lookup_flags includes LookupFlags::IgnoreLigatures
1558ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org   */
1568ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  if (property & lookup_flags & LookupFlag::IgnoreFlags)
1578ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    return false;
1588ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org
1598ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
1608ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  {
1618ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    /* If using mark filtering sets, the high short of
1628ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org     * lookup_flags has the set index.
1638ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org     */
1648ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org    if (lookup_flags & LookupFlag::UseMarkFilteringSet)
165dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org      return _get_gdef (face).mark_set_covers (lookup_flags >> 16, ginfo->codepoint);
166dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
167dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    /* The second byte of lookup_flags has the meaning
168d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org     * "ignore marks of attachment type different than
169d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org     * the attachment type specified."
170d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org     */
171d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (lookup_flags & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
172d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      return (lookup_flags & LookupFlag::MarkAttachmentType) == (property & LookupFlag::MarkAttachmentType);
173d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
174d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
175d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return true;
176d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
177d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
178d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orghb_bool_t
179d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org_hb_ot_layout_skip_mark (hb_face_t    *face,
180d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org			 hb_internal_glyph_info_t *ginfo,
181d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org			 unsigned int  lookup_flags,
182d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org			 unsigned int *property_out)
183d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org{
184d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  unsigned int property;
185d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
186d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
187d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    ginfo->gproperty = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
188d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  property = ginfo->gproperty;
189d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (property_out)
190d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    *property_out = property;
191d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
192d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
193d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  {
194d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    /* Skip mark if lookup_flags includes LookupFlags::IgnoreMarks */
195d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (lookup_flags & LookupFlag::IgnoreMarks)
196d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      return true;
197d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
198d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    /* If using mark filtering sets, the high short of lookup_flags has the set index. */
199d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (lookup_flags & LookupFlag::UseMarkFilteringSet)
200d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      return !_get_gdef (face).mark_set_covers (lookup_flags >> 16, ginfo->codepoint);
201d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
202d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    /* The second byte of lookup_flags has the meaning "ignore marks of attachment type
2039af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org     * different than the attachment type specified." */
2049af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    if (lookup_flags & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
2059af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org      return (lookup_flags & LookupFlag::MarkAttachmentType) != (property & LookupFlag::MarkAttachmentType);
2069af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  }
2079af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
2089af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return false;
2099af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org}
2109af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
2119af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgvoid
2129af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org_hb_ot_layout_set_glyph_class (hb_face_t                  *face,
2139af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org			       hb_codepoint_t              glyph,
2149af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org			       hb_ot_layout_glyph_class_t  klass)
2159af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org{
2169af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (HB_OBJECT_IS_INERT (face))
2179af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    return;
2189af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
2199af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  /* TODO optimize this? similar to old harfbuzz code for example */
2209af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
2219af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  hb_ot_layout_t *layout = face->ot_layout;
2229af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  hb_ot_layout_class_t gdef_klass;
2239af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  unsigned int len = layout->new_gdef.len;
2249af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
2259af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (unlikely (glyph > 65535))
2269af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    return;
2279af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
228750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  /* XXX this is not threadsafe */
229750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (glyph >= len) {
230750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    unsigned int new_len;
231750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    unsigned char *new_klasses;
232750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
233750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    new_len = len == 0 ? 120 : 2 * len;
234750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    while (new_len <= glyph)
235750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      new_len *= 2;
236e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
237e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    if (new_len > 65536)
238e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      new_len = 65536;
239750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    new_klasses = (unsigned char *) realloc (layout->new_gdef.klasses, new_len * sizeof (unsigned char));
240750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
241750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    if (unlikely (!new_klasses))
242750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      return;
243750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
244750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    memset (new_klasses + len, 0, new_len - len);
245750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
246750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    layout->new_gdef.klasses = new_klasses;
247750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    layout->new_gdef.len = new_len;
248750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
249750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
250750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  switch (klass) {
251750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  default:
252750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  case HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED:	gdef_klass = GDEF::UnclassifiedGlyph;	break;
253750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  case HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH:	gdef_klass = GDEF::BaseGlyph;		break;
254750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  case HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE:	gdef_klass = GDEF::LigatureGlyph;	break;
255750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  case HB_OT_LAYOUT_GLYPH_CLASS_MARK:		gdef_klass = GDEF::MarkGlyph;		break;
256750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  case HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT:	gdef_klass = GDEF::ComponentGlyph;	break;
257750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
258e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
259750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  layout->new_gdef.klasses[glyph] = gdef_klass;
260e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  return;
261e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
262750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
263750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid
264750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org_hb_ot_layout_set_glyph_property (hb_face_t      *face,
265e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org				  hb_codepoint_t  glyph,
266e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org				  unsigned int    property)
267e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org{ _hb_ot_layout_set_glyph_class (face, glyph, (hb_ot_layout_glyph_class_t) (property & 0xff)); }
268750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
269750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
270750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orghb_ot_layout_glyph_class_t
271e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orghb_ot_layout_get_glyph_class (hb_face_t      *face,
272750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org			      hb_codepoint_t  glyph)
273750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org{
274750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return (hb_ot_layout_glyph_class_t) (_hb_ot_layout_get_glyph_property (face, glyph) & 0xff);
275e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
276750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
277750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid
278e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orghb_ot_layout_set_glyph_class (hb_face_t                 *face,
279750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org			      hb_codepoint_t             glyph,
280750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org			      hb_ot_layout_glyph_class_t klass)
281750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org{
282750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  _hb_ot_layout_set_glyph_class (face, glyph, klass);
283750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
284750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
285750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid
286750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orghb_ot_layout_build_glyph_classes (hb_face_t      *face,
287750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				  hb_codepoint_t *glyphs,
288750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				  unsigned char  *klasses,
289750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				  uint16_t        count)
290750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org{
291750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (HB_OBJECT_IS_INERT (face))
292750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return;
293750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
294750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  hb_ot_layout_t *layout = face->ot_layout;
295750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
296750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (unlikely (!count || !glyphs || !klasses))
297750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return;
298e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
299e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (layout->new_gdef.len == 0) {
300750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    layout->new_gdef.klasses = (unsigned char *) calloc (count, sizeof (unsigned char));
301750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    layout->new_gdef.len = count;
302750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
303e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
304e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  for (unsigned int i = 0; i < count; i++)
305750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    _hb_ot_layout_set_glyph_class (face, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]);
306750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
307750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
308e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgunsigned int
309e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orghb_ot_layout_get_attach_points (hb_face_t      *face,
310750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				hb_codepoint_t  glyph,
311750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				unsigned int    start_offset,
312750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				unsigned int   *point_count /* IN/OUT */,
313e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org				unsigned int   *point_array /* OUT */)
314e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org{
315750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array);
316750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
317e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
318e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgunsigned int
319750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orghb_ot_layout_get_lig_carets (hb_font_t      *font,
320750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org			     hb_face_t      *face,
321750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org			     hb_codepoint_t  glyph,
322e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org			     unsigned int    start_offset,
323e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org			     unsigned int   *caret_count /* IN/OUT */,
324e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org			     int            *caret_array /* OUT */)
325e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org{
326e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  hb_ot_layout_context_t c;
327e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  c.font = font;
328750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  c.face = face;
329750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return _get_gdef (face).get_lig_carets (&c, glyph, start_offset, caret_count, caret_array);
330750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
331750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
332750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org/*
333750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * GSUB/GPOS
334750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org */
335e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
336750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgstatic const GSUBGPOS&
337750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgget_gsubgpos_table (hb_face_t *face,
338750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org		    hb_tag_t   table_tag)
339750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org{
340750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  switch (table_tag) {
341750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case HB_OT_TAG_GSUB: return _get_gsub (face);
342750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    case HB_OT_TAG_GPOS: return _get_gpos (face);
343750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    default:             return Null(GSUBGPOS);
344750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  }
345750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
346750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
347750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
348750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgunsigned int
349750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orghb_ot_layout_table_get_script_tags (hb_face_t    *face,
350750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				    hb_tag_t      table_tag,
351750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				    unsigned int  start_offset,
352750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				    unsigned int *script_count /* IN/OUT */,
353750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				    hb_tag_t     *script_tags /* OUT */)
354750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org{
355750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
356750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
357750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return g.get_script_tags (start_offset, script_count, script_tags);
358e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org}
359750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
360750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orghb_bool_t
361750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orghb_ot_layout_table_find_script (hb_face_t    *face,
362750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				hb_tag_t      table_tag,
363e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org				hb_tag_t      script_tag,
364750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				unsigned int *script_index)
365750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org{
366750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
367750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
368e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
369750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (g.find_script_index (script_tag, script_index))
370750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return TRUE;
371750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
372e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  /* try finding 'DFLT' */
373202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
374202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return FALSE;
375202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
376ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
377ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
3783484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    return FALSE;
3793484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
3803484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
3813484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return FALSE;
3823484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org}
3833484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org
3843484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orghb_bool_t
3853484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.orghb_ot_layout_table_choose_script (hb_face_t      *face,
3863484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org				  hb_tag_t        table_tag,
387ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org				  const hb_tag_t *script_tags,
388ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org				  unsigned int   *script_index)
389ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org{
390e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
391e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
392e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
393e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  while (*script_tags)
394e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  {
395e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    if (g.find_script_index (*script_tags, script_index))
396e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      return TRUE;
397e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    script_tags++;
398e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  }
399e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
400e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  /* try finding 'DFLT' */
401e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
402e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    return FALSE;
403e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
4048ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
405e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
406e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    return FALSE;
407e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
408ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
4093484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  return FALSE;
41043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
411750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
4122ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.orgunsigned int
4132ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.orghb_ot_layout_table_get_feature_tags (hb_face_t    *face,
4142ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org				     hb_tag_t      table_tag,
4157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org				     unsigned int  start_offset,
4167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org				     unsigned int *feature_count /* IN/OUT */,
4177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org				     hb_tag_t     *feature_tags /* OUT */)
4187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org{
4198f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
4207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
421750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return g.get_feature_tags (start_offset, feature_count, feature_tags);
422750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
4232ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org
424750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
425e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orgunsigned int
426e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.orghb_ot_layout_script_get_language_tags (hb_face_t    *face,
427e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org				       hb_tag_t      table_tag,
428e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org				       unsigned int  script_index,
429750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org				       unsigned int  start_offset,
4302ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org				       unsigned int *language_count /* IN/OUT */,
4312ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org				       hb_tag_t     *language_tags /* OUT */)
4322ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org{
433662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
4342ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org
4352ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  return s.get_lang_sys_tags (start_offset, language_count, language_tags);
4362ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org}
4372ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org
438e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orghb_bool_t
439e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orghb_ot_layout_script_find_language (hb_face_t    *face,
4401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org				   hb_tag_t      table_tag,
4411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org				   unsigned int  script_index,
4428f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org				   hb_tag_t      language_tag,
443ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org				   unsigned int *language_index)
4442ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org{
445ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
4462ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
447de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
448202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  if (s.find_lang_sys_index (language_tag, language_index))
449202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return TRUE;
45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
45243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
4532ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org    return FALSE;
4542ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org
4552ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
4562ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org  return FALSE;
457202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org}
458e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenhb_bool_t
4602ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.orghb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
4612ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org						  hb_tag_t      table_tag,
46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen						  unsigned int  script_index,
46343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen						  unsigned int  language_index,
46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen						  unsigned int *feature_index)
465474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org{
466474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  const LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
467474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
468e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (feature_index) *feature_index = l.get_required_feature_index ();
469c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
470e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  return l.has_required_feature ();
471e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
472e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
473e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgunsigned int
47451e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.orghb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
47551e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org					   hb_tag_t      table_tag,
476e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					   unsigned int  script_index,
477e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					   unsigned int  language_index,
478e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					   unsigned int  start_offset,
479e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					   unsigned int *feature_count /* IN/OUT */,
480e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					   unsigned int *feature_indexes /* OUT */)
481e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org{
482e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
483e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
484e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
485e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
486e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
487e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
488e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgunsigned int
489e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orghb_ot_layout_language_get_feature_tags (hb_face_t    *face,
490e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					hb_tag_t      table_tag,
491e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					unsigned int  script_index,
492e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					unsigned int  language_index,
493e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					unsigned int  start_offset,
494e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					unsigned int *feature_count /* IN/OUT */,
495e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					hb_tag_t     *feature_tags /* OUT */)
496e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org{
497e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
498e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
499e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
500e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
501f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);
502e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
503e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  if (feature_tags) {
504e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    unsigned int count = *feature_count;
505e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    for (unsigned int i = 0; i < count; i++)
506e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org      feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]);
507e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  }
508e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
509e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  return ret;
510e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
511e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
512e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
513e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orghb_bool_t
514e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orghb_ot_layout_language_find_feature (hb_face_t    *face,
515e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org				    hb_tag_t      table_tag,
516e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org				    unsigned int  script_index,
517e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org				    unsigned int  language_index,
518e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org				    hb_tag_t      feature_tag,
519e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org				    unsigned int *feature_index)
520e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org{
521e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
522e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
523e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
524e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  unsigned int num_features = l.get_feature_count ();
526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  for (unsigned int i = 0; i < num_features; i++) {
527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    unsigned int f_index = l.get_feature_index (i);
528202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org
529202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    if (feature_tag == g.get_feature_tag (f_index)) {
530202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      if (feature_index) *feature_index = f_index;
531c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org      return TRUE;
532c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    }
533e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  }
534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
535202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return FALSE;
537202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org}
538e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comunsigned int
5402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orghb_ot_layout_feature_get_lookup_indexes (hb_face_t    *face,
541bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org					 hb_tag_t      table_tag,
542bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org					 unsigned int  feature_index,
543bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org					 unsigned int  start_offset,
544e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					 unsigned int *lookup_count /* IN/OUT */,
545e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org					 unsigned int *lookup_indexes /* OUT */)
546e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org{
547e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
548e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  const Feature &f = g.get_feature (feature_index);
549e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
550e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org  return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
551e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
552e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
553e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
554e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org/*
555e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org * GSUB
556e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org */
557e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
558e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orghb_bool_t
55951e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.orghb_ot_layout_has_substitution (hb_face_t *face)
56051e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org{
56151e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org  return &_get_gsub (face) != &Null(GSUB);
562e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org}
563e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org
564e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orghb_bool_t
565e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orghb_ot_layout_substitute_lookup (hb_face_t    *face,
5668ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org				hb_buffer_t  *buffer,
5671845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org				unsigned int  lookup_index,
5681845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org				hb_mask_t     mask)
5698ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org{
5708ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  hb_ot_layout_context_t c;
5718ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  c.font = NULL;
5728ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  c.face = face;
5738ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  return _get_gsub (face).substitute_lookup (&c, buffer, lookup_index, mask);
5748ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org}
5758ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org
5768d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
5778d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org/*
5788d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org * GPOS
5798d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org */
5808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
5818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orghb_bool_t
5828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orghb_ot_layout_has_positioning (hb_face_t *face)
5838f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org{
5848ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org  return &_get_gpos (face) != &Null(GPOS);
5858ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org}
5868ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org
5878ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orghb_bool_t
5888ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orghb_ot_layout_position_lookup   (hb_font_t    *font,
58943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen				hb_face_t    *face,
5908ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org				hb_buffer_t  *buffer,
5918ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org				unsigned int  lookup_index,
5928ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org				hb_mask_t     mask)
59343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen{
59443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  hb_ot_layout_context_t c;
59543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  c.font = font;
5961845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  c.face = face;
5971845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return _get_gpos (face).position_lookup (&c, buffer, lookup_index, mask);
5981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org}
5991845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org
6001845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgvoid
6018d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orghb_ot_layout_position_finish (hb_font_t    *font HB_UNUSED,
6028d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org			      hb_face_t    *face HB_UNUSED,
6038d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org			      hb_buffer_t  *buffer)
604870a0b67c822d289024711912e2512af01b66c3bager@chromium.org{
605870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  unsigned int i, j;
606474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  unsigned int len = hb_buffer_get_length (buffer);
607474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  hb_internal_glyph_position_t *pos = (hb_internal_glyph_position_t *) hb_buffer_get_glyph_positions (buffer);
608474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
609474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  /* TODO: Vertical */
610474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org
611474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  /* Handle cursive connections */
612474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  /* First handle all left-to-right connections */
613474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  for (j = 0; j < len; j++) {
614474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (pos[j].cursive_chain > 0)
615870a0b67c822d289024711912e2512af01b66c3bager@chromium.org    {
616870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      pos[j].y_offset += pos[j - pos[j].cursive_chain].y_offset;
617870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      pos[j].cursive_chain = 0;
6188d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    }
6198d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
620870a0b67c822d289024711912e2512af01b66c3bager@chromium.org  /* Then handle all right-to-left connections */
6218d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  for (i = len; i > 0; i--) {
6228d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    j = i - 1;
623474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (pos[j].cursive_chain < 0)
624474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    {
625474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      pos[j].y_offset += pos[j - pos[j].cursive_chain].y_offset;
626474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      pos[j].cursive_chain = 0;
627474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    }
628474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  }
6298d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
6308d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  /* Handle attachments */
631474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org  for (i = 0; i < len; i++)
632474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org    if (pos[i].back)
6338d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    {
634870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      unsigned int back = i - pos[i].back;
635870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      pos[i].back = 0;
636870a0b67c822d289024711912e2512af01b66c3bager@chromium.org      pos[i].x_offset += pos[back].x_offset;
637f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      pos[i].y_offset += pos[back].y_offset;
6382abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
6392abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      if (buffer->props.direction == HB_DIRECTION_RTL)
6402abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org	for (j = back + 1; j < i + 1; j++) {
641b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org	  pos[i].x_offset += pos[j].x_advance;
6422abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org	  pos[i].y_offset += pos[j].y_advance;
643b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org	}
6442abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org      else
6452abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org	for (j = back; j < i; j++) {
6462abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org	  pos[i].x_offset -= pos[j].x_advance;
6472abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org	  pos[i].y_offset -= pos[j].y_advance;
6482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org	}
6492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    }
6502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org}
6512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
6522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org
6532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgHB_END_DECLS
6542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org