aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/freetype2/src/otlayout/otlparse.c
blob: 705c0c60fa80c596db918a8363be228e19fb122c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "otlparse.h"
#include "otlutils.h"

  static void
  otl_string_ensure( OTL_String  string,
                     OTL_UInt    count,
                     OTL_Parser  parser )
  {
    count += string->length;

    if ( count > string->capacity )
    {
      OTL_UInt    old_count = string->capacity;
      OTL_UInt    new_count = old_count;
      OTL_Memory  memory    = parser->memory;

      while ( new_count < count )
        new_count += (new_count >> 1) + 16;

      if ( OTL_MEM_RENEW_ARRAY( string->glyphs, old_count, new_count ) )
        otl_parser_error( parser, OTL_Parse_Err_Memory );

      string->capacity = new_count;
    }
  }

#define  OTL_STRING_ENSURE(str,count,parser)                   \
           OTL_BEGIN_STMNT                                     \
             if ( (str)->length + (count) > (str)>capacity )   \
               otl_string_ensure( str, count, parser );        \
           OTL_END_STMNT


  OTL_LOCALDEF( OTL_UInt )
  otl_parser_get_gindex( OTL_Parser  parser )
  {
    OTL_String  in = parser->str_in;

    if ( in->cursor >= in->num_glyphs )
      otl_parser_error( parser, OTL_Err_Parser_Internal );

    return in->str[ in->cursor ].gindex;
  }


  OTL_LOCALDEF( void )
  otl_parser_error( OTL_Parser      parser,
                    OTL_ParseError  error; )
  {
    parser->error = error;
    otl_longjmp( parser->jump_buffer, 1 );
  }

#define  OTL_PARSER_UNCOVERED(x)  otl_parser_error( x, OTL_Parse_Err_UncoveredGlyph );

  OTL_LOCAL( void )
  otl_parser_check_property( OTL_Parser  parser,
                             OTL_UInt    gindex,
                             OTL_UInt    flags,
                             OTL_UInt   *aproperty );

  OTL_LOCALDEF( void )
  otl_parser_replace_1( OTL_Parser  parser,
                        OTL_UInt    gindex )
  {
    OTL_String       in  = parser->str_in;
    OTL_String       out = parser->str_out;
    OTL_StringGlyph  glyph, in_glyph;

    /* sanity check */
    if ( in == NULL               ||
         out == NULL              ||
         in->length == 0          ||
         in->cursor >= in->length )
    {
      /* report as internal error, since these should */
      /* never happen !!                              */
      otl_parser_error( parser, OTL_Err_Parse_Internal );
    }

    OTL_STRING_ENSURE( out, 1, parser );
    glyph    = out->glyphs + out->length;
    in_glyph = in->glyphs  + in->cursor;

    glyph->gindex        = gindex;
    glyph->property      = in_glyph->property;
    glyph->lig_component = in_glyph->lig_component;
    glyph->lig_id        = in_glyph->lig_id;

    out->length += 1;
    out->cursor  = out->length;
    in->cursor  += 1;
  }

  OTL_LOCALDEF( void )
  otl_parser_replace_n( OTL_Parser  parser,
                        OTL_UInt    count,
                        OTL_Bytes   indices )
  {
    OTL_UInt         lig_component, lig_id, property;
    OTL_String       in  = parser->str_in;
    OTL_String       out = parser->str_out;
    OTL_StringGlyph  glyph, in_glyph;
    OTL_Bytes        p = indices;

    /* sanity check */
    if ( in == NULL               ||
         out == NULL              ||
         in->length == 0          ||
         in->cursor >= in->length )
    {
      /* report as internal error, since these should */
      /* never happen !!                              */
      otl_parser_error( parser, OTL_Err_Parse_Internal );
    }

    OTL_STRING_ENSURE( out, count, parser );
    glyph    = out->glyphs + out->length;
    in_glyph = in->glyphs  + in->cursor;

    glyph->gindex = gindex;

    lig_component = in_glyph->lig_component;
    lig_id        = in_glyph->lid_id;
    property      = in_glyph->property;

    for ( ; count > 0; count-- )
    {
      glyph->gindex        = OTL_NEXT_USHORT(p);
      glyph->property      = property;
      glyph->lig_component = lig_component;
      glyph->lig_id        = lig_id;

      out->length ++;
    }

    out->cursor  = out->length;
    in->cursor  += 1;
  }