ApwFreetypeLibrary

Check-in [ba5a7822b2]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:initial verwsion.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ba5a7822b2a823105b587115a39914a48831ea3b
User & Date: arnulf 2014-12-29 21:44:25
Context
2014-12-29
21:46
initial version. check-in: e10740ef9b user: arnulf tags: trunk
21:44
initial verwsion. check-in: ba5a7822b2 user: arnulf tags: trunk
21:43
initial version check-in: 8b3b803ceb user: arnulf tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added ftbase/FTGlyphLoadRec.java.

















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTGlyphLoadRec                                                          */
  /*                                                                       */
  /* ===================================================================== */

public class FTGlyphLoadRec extends Object {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTGlyphLoadRec";

    public FTOutlineRec outline = null;            /* outline                   */
    public FTVectorRec[] extra_points = null;  /* extra points table        */
    public FTVectorRec[] extra_points2 = null; /* second extra points table */
    public int num_subglyphs = 0;                  /* number of subglyphs       */
    public FTSubGlyphRec[] subglyphs = null;       /* subglyphs                 */
    public int subglyphs_idx;
    public int extra_points_idx = 0;
    public int extra_points2_idx = 0;

    /* ==================== FTGlyphLoadRec ================================== */
    public FTGlyphLoadRec() {
      oid++;
      id = oid;
      outline = new FTOutlineRec();
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* ==================== copy ===================================== */
    public int copy( FTGlyphLoadRec from ) {
      outline.copy(from.outline);
      extra_points = from.extra_points;
      extra_points2 = from.extra_points2;
      num_subglyphs = from.num_subglyphs;
      subglyphs = from.subglyphs;
      subglyphs_idx = from.subglyphs_idx;
      extra_points_idx = from.extra_points_idx;
      extra_points2_idx = from.extra_points2_idx;
      return 0;
    }

}

Added ftbase/FTGlyphLoaderFuncs.java.























































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
// ----------------------------------------------------------------
// FTGlyphLoaderFuncs.java --
//
// Copyright (c) 2014 by Arnulf P. Wiedemann
//
// See the file "license.terms" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//------------------------------------------------------------------------

package ftbase;

//import android.util.Log;

/* ======================================================================= */
/*  This Java implementation is derived from the Freetype code             */
/*  and has been implemented for reading .ttf font files                   */
/*                                                                         */
/*  Copyright (C) of the Java implementation 2014                          */
/*  Arnulf Wiedemann                                                       */
/*                                                                         */
/*  See the file "license.terms" for information on usage and              */
/*  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.   */
/*                                                                         */
/*  in this directory the truetype opcode interpreter is ported to Java    */
/*                                                                         */
/*  the next blocks are taken from the original source code                */
/*                                                                         */
/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
/*            2010 by                                                      */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/* ======================================================================= */

  /* ===================================================================== */
  /*    FTGlyphLoaderFuncs                                                 */
  /*                                                                       */
  /* ===================================================================== */

public class FTGlyphLoaderFuncs extends Object {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTGlyphLoaderFuncs";

    /* ==================== FTGlyphLoaderFuncs ================================== */
    public FTGlyphLoaderFuncs() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      String str = TAG+"!"+id+"!";
      return str;
    } 
        
    /* ==================== toString ===================================== */
    public String toString() {
      StringBuffer str = new StringBuffer(mySelf()+"!");
      return str.toString();
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }

    /* =====================================================================
     * ft_new_glyph
     * =====================================================================
     */
    public static int ft_new_glyph(FTLibraryRec library, FTGlyphClassRec clazz, FTReference<FTGlyphRec> glyph_ref) {
      int  error = 0;
      FTGlyphRec glyph = null;

      glyph_ref.Set(null);
      glyph = new FTGlyphRec();
      if (glyph != null) {
        glyph.library = library;
        glyph.clazz   = clazz;
        glyph.format  = clazz.glyph_format;
        glyph_ref.Set(glyph);
      }
      return error;
    }
    
    /* =====================================================================
     * ft_lookup_glyph_renderer
     * =====================================================================
     */
    public static FTRendererRec ft_lookup_glyph_renderer(FTGlyphSlotRec slot) {
      FTFaceRec face = slot.face;
      FTLibraryRec library = face.driver.library;
      FTRendererRec result = library.cur_renderer;


      if (result == null|| result.glyph_format != slot.format) {
        result = FTRendererRec.FTLookupRenderer(library, slot.format, null);
      }
      return result;
    }
    
    /* =====================================================================
     * ft_glyphslot_clear
     * =====================================================================
     */
    public static void ft_glyphslot_clear(FTReference<FTGlyphSlotRec> slot_ref) {
      FTGlyphSlotRec slot = null;

      /* free bitmap if needed */
      ft_glyphslot_free_bitmap(slot_ref);
      slot = slot_ref.Get();
      /* clear all public fields in the glyph slot */
      slot.metrics.clear();
      slot.outline.clear();
      slot.bitmap.width = 0;
      slot.bitmap.rows = 0;
      slot.bitmap.pitch = 0;
      slot.bitmap.pixel_mode = 0;
      /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */
      slot.bitmap_left = 0;
      slot.bitmap_top = 0;
      slot.num_subglyphs = 0;
      slot.subglyphs = null;
      slot.control_data = 0;
      slot.control_len = 0;
      slot.other = 0;
      slot.format = FTGlyphFormat.FT_GLYPH_FORMAT_NONE;
      slot.linearHoriAdvance = 0L;
      slot.linearVertAdvance = 0L;
      slot.lsb_delta = 0L;
      slot.rsb_delta = 0L;
      slot_ref.Set(slot);
    }

    /* =====================================================================
     * ft_glyphslot_free_bitmap
     * =====================================================================
     */
    public static void ft_glyphslot_free_bitmap(FTReference<FTGlyphSlotRec> slot_ref) {
      FTGlyphSlotRec slot = slot_ref.Get();
      if ((slot.internal != null) &&
    		  (slot.internal.flags & FTGlyphLoaderFlags.FT_GLYPH_OWN_BITMAP) != 0) {
//        FT_FREE( slot.bitmap.buffer );
        slot.internal.flags &= ~FTGlyphLoaderFlags.FT_GLYPH_OWN_BITMAP;
      } else {
        /* assume that the bitmap buffer was stolen or not */
        /* allocated from the heap                         */
        slot.bitmap.buffer = null;
      }
      slot_ref.Set(slot);
    }

    /* =====================================================================
     * compute_glyph_metrics
     * =====================================================================
     */
    public static int compute_glyph_metrics(FTReference<TTLoaderRec> loader_ref,
            int glyph_index) {
if (FTGlyphLoaderRec.glyph_debug > 2) {
System.out.println("compute_glyph_metrics");
}
      TTLoaderRec loader = loader_ref.Get();
      int error = 0;
      TTFaceRec face = (TTFaceRec)loader.face;
      FTBBoxRec bbox;
      long y_scale;
      FTGlyphSlotRec glyph = loader.glyph;
      TTSizeRec size = (TTSizeRec)loader.size;

int i;
for (i = 0; i < loader.gloader.current.outline.n_points + 4; i++) {
//System.out.println(String.format("PP2: i: %d x: %d y: %d\n", i, loader.gloader.current.outline.points[loader.gloader.current.outline.points_idx + i].x,
//loader.gloader.current.outline.points[loader.gloader.current.outline.points_idx + i].y));
}
      y_scale = 0x10000L;
      if ((loader.load_flags & FTGlyphLoaderFlags.FT_LOAD_NO_SCALE) == 0) {
        y_scale = size.metrics.y_scale;
      }
      if (glyph.format != FTGlyphFormat.FT_GLYPH_FORMAT_COMPOSITE) {
        FTReference<FTOutlineRec> outline_ref = new FTReference<FTOutlineRec>();
        FTReference<FTBBoxRec> bbox_ref = new FTReference<FTBBoxRec>();
        outline_ref.Set(glyph.outline);
        bbox_ref.Set(new FTBBoxRec());
        FTOutlineRec.FTOutlineGetCBox(outline_ref, bbox_ref);
        glyph.outline = outline_ref.Get();
        bbox = bbox_ref.Get();
      } else {
        bbox = loader.bbox;
      }
      /* get the device-independent horizontal advance; it is scaled later */
      /* by the base layer.                                                */
      glyph.linearHoriAdvance = loader.linear;
      glyph.metrics.horiBearingX = bbox.xMin;
      glyph.metrics.horiBearingY = bbox.yMax;
      glyph.metrics.horiAdvance = loader.pp2.x - loader.pp1.x;
      /* adjust advance width to the value contained in the hdmx table */
      if (face.postscript.isFixedPitch != 0 &&
           (loader.load_flags & FTGlyphLoaderFlags.FT_LOAD_NO_HINTING) == 0) {
        int widthpIdx;

        widthpIdx = TTLoad.tt_face_get_device_metrics(face, size.metrics.x_ppem, glyph_index);
        if (widthpIdx != 0) {
          glyph.metrics.horiAdvance = (long)(face.hdmx_table[widthpIdx] << 6);
        }
      }
      /* set glyph dimensions */
      glyph.metrics.width = bbox.xMax - bbox.xMin;
      glyph.metrics.height = bbox.yMax - bbox.yMin;
      /* Now take care of vertical metrics.  In the case where there is */
      /* no vertical information within the font (relatively common),   */
      /* create some metrics manually                                   */
      {
        long top;      /* scaled vertical top side bearing  */
        long advance;  /* scaled vertical advance height    */

        /* Get the unscaled top bearing and advance height. */
        if (face.vertical_info && face.vertical.number_Of_VMetrics > 0) {
          top = FTCalc.FTDivFix(loader.pp3.y - bbox.yMax, y_scale);
          if (loader.pp3.y <= loader.pp4.y) {
            advance = 0;
          } else {
            advance = FTCalc.FTDivFix(loader.pp3.y - loader.pp4.y, y_scale);
          }
        } else {
          long height;

          /* XXX Compute top side bearing and advance height in  */
          /*     Get_VMetrics instead of here.                   */

          /* NOTE: The OS/2 values are the only `portable' ones, */
          /*       which is why we use them, if there is an OS/2 */
          /*       table in the font.  Otherwise, we use the     */
          /*       values defined in the horizontal header.      */
          height = FTCalc.FTDivFix(bbox.yMax - bbox.yMin, y_scale);
          if (face.os2.version != 0xFFFF) {
            advance = (long)(face.os2.sTypoAscender - face.os2.sTypoDescender);
          } else {
            advance = (long)(face.horizontal.Ascender - face.horizontal.Descender);
          }
          top = (advance - height) / 2;
        }
        glyph.linearVertAdvance = advance;
        /* scale the metrics */
        if ((loader.load_flags & FTGlyphLoaderFlags.FT_LOAD_NO_SCALE) == 0) {
          top = FTCalc.FTMulFix(top, y_scale);
          advance = FTCalc.FTMulFix(advance, y_scale);
        }
        /* XXX: for now, we have no better algorithm for the lsb, but it */
        /*      should work fine.                                        */
        /*                                                               */
        glyph.metrics.vertBearingX = glyph.metrics.horiBearingX -
                                        glyph.metrics.horiAdvance / 2;
        glyph.metrics.vertBearingY = top;
        glyph.metrics.vertAdvance = advance;
      }
      return error;
    }

}

Added ftbase/FTGlyphLoaderRec.java.























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
// ----------------------------------------------------------------
// FTGlyphLoaderRec.java --
//
// Copyright (c) 2014 by Arnulf P. Wiedemann
//
// See the file "license.terms" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//------------------------------------------------------------------------

package ftbase;

import android.util.Log;
import org.apwtcl.gles20.batikfont.ftraster.*;

/* ======================================================================= */
/*  This Java implementation is derived from the Freetype code             */
/*  and has been implemented to work together with the Apache batik code   */
/*  for reading .ttf ont files                                             */
/*                                                                         */
/*  Copyright (C) of the Java implementation 2014                          */
/*  Arnulf Wiedemann                                                       */
/*                                                                         */
/*  See the file "license.terms" for information on usage and              */
/*  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.   */
/*                                                                         */
/*  in this directory the truetype opcode interpreter is ported to Java    */
/*                                                                         */
/*  the next blocks are taken from the original source code                */
/*                                                                         */
/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
/*            2010 by                                                      */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/* ======================================================================= */

  /* ===================================================================== */
  /*    FTGlyphLoaderRec                                                   */
  /*                                                                       */
  /* ===================================================================== */

public class FTGlyphLoaderRec extends Object {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTGlyphLoaderRec";

    public static TTGlyphZoneRec loaderZone = null;
    public static FTGlyphLoadRec loaderLoad = null;
    public static FTGlyphLoaderRec loaderGloader = null;
    
    public static boolean doDebug = false;
    public static int glyph_debug = 0;

    public int max_points = 0;
    public int max_contours = 0;
    public int max_subglyphs = 0;
    public boolean use_extra = false;
    public FTGlyphLoadRec base = null;
    public FTGlyphLoadRec current = null;
    public int base_idx;
    public int current_idx;

    /* ==================== FTGlyphLoaderRec ================================== */
    public FTGlyphLoaderRec() {
      oid++;
      id = oid;
      base = new FTGlyphLoadRec();
      current = new FTGlyphLoadRec();
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      String str = TAG+"!"+id+"!";
      return str;
    } 
        
    /* ==================== toString ===================================== */
    public String toString() {
      StringBuffer str = new StringBuffer(mySelf()+"!");
      return str.toString();
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* ==================== _showLoaderZone ================================== */
    public static void _showLoaderZone(String str) {
      int j;

      if (doDebug) {
        System.out.println(String.format("%s", str));
        if (TTGlyphLoaderFuncs.loader != null) {
          loaderZone = TTGlyphLoaderFuncs.loader.zone;
          loaderLoad = TTGlyphLoaderFuncs.loader.gloader.current;
        }
        if (TTInterpBase.cur != null) {
          if (TTInterpBase.cur.zp0 != null) {
            if (TTInterpBase.cur.zp0.cur != null) {
              System.out.println("zp0.cur: "+(Object)TTInterpBase.cur.zp0.cur);
              System.out.println("zp0.org: "+(Object)TTInterpBase.cur.zp0.org);
              System.out.println("zp0.orus: "+(Object)TTInterpBase.cur.zp0.orus);
            }
          }
          if (TTInterpBase.cur.zp1 != null) {
            if (TTInterpBase.cur.zp1.cur != null) {
              System.out.println("zp1.cur: "+(Object)TTInterpBase.cur.zp1.cur);
              System.out.println("zp1.org: "+(Object)TTInterpBase.cur.zp1.org);
              System.out.println("zp1.orus: "+(Object)TTInterpBase.cur.zp1.orus);
            }
          }
          if (TTInterpBase.cur.zp2 != null) {
            if (TTInterpBase.cur.zp2.cur != null) {
              System.out.println("zp2.cur: "+(Object)TTInterpBase.cur.zp2.cur);
              System.out.println("zp2.org: "+(Object)TTInterpBase.cur.zp2.org);
              System.out.println("zp2.orus: "+(Object)TTInterpBase.cur.zp2.orus);
	    }
	  }
        }
        if (loaderZone != null) {
          System.out.println(String.format("loaderZone: n_points: %d\n", loaderZone.n_points));
          if (loaderZone.cur != null) {
            System.out.println("loaderZone.cur: "+(Object)loaderZone.cur+"!"+loaderZone.cur_idx);
          }
          if (loaderZone.orus != null) {
            System.out.println("loaderZone.orus: "+(Object)loaderZone.orus+"!"+loaderZone.orus_idx);
          }
          if (loaderZone.cur != null) {
            System.out.println("loaderZone.org: "+(Object)loaderZone.org+"!"+loaderZone.org_idx);
          }
        }
        if (loaderLoad != null) {
          System.out.println(String.format("loaderLoad: n_points: %d", loaderLoad.outline.n_points));
          if (loaderLoad.outline.points != null) {
            System.out.println("loaderLoad.outline.points: "+(Object)loaderLoad.outline.points+"!"+loaderLoad.outline.points_idx);
          }
          if (loaderLoad.extra_points != null) {
            System.out.println("loaderLoad.extra_points: "+(Object)loaderLoad.extra_points+"!"+loaderLoad.extra_points_idx);
          }
          if (loaderLoad.extra_points2 != null) {
            System.out.println("loaderLoad.extra_points2: "+(Object)loaderLoad.extra_points2+"!"+loaderLoad.extra_points2_idx);
          }
        }
        if (loaderZone != null) {
  System.out.println("Show loaderZone");
          for (j = 0; j < loaderZone.n_points; j++) {
            if (loaderZone.cur != null) {
              if (j < loaderZone.cur.length) {
                if (loaderZone.cur[loaderZone.cur_idx + j] != null) {
                  System.out.println(String.format("  cur: %d %5d %5d", j, loaderZone.cur[loaderZone.cur_idx + j].x, loaderZone.cur[loaderZone.cur_idx + j].y));
                }
              }
            }
            if (loaderZone.orus != null) {
              if (j < loaderZone.orus.length) {
                if (loaderZone.orus[loaderZone.orus_idx + j] != null) {
                  System.out.println(String.format(" orus: %d %5d %5d", j, loaderZone.orus[loaderZone.orus_idx + j].x, loaderZone.orus[loaderZone.orus_idx + j].y));
                }
              }
            }
            if (loaderZone.org != null) {
              if (j < loaderZone.org.length) {
                if (loaderZone.org[loaderZone.org_idx + j] != null) {
                  System.out.println(String.format("  org: %d %5d %5d", j, loaderZone.org[loaderZone.org_idx + j].x, loaderZone.org[loaderZone.org_idx + j].y));
                }
              }
            }
          }
        }
        if (loaderLoad != null) {
System.out.println("Show loaderLoad");
          for (j = 0; j < loaderLoad.outline.n_points; j++) {
            if (loaderLoad.outline.points != null) {
              if (loaderLoad.outline.points_idx + j < loaderLoad.outline.points.length) {
                if (loaderLoad.outline.points[loaderLoad.outline.points_idx + j] != null) {
                  System.out.println(String.format(" outl: %d %5d %5d", j, loaderLoad.outline.points[loaderLoad.outline.points_idx + j].x, loaderLoad.outline.points[loaderLoad.outline.points_idx + j].y));
                }
              }
            }
            if (loaderLoad.extra_points != null) {
              if (j < loaderLoad.extra_points.length) {
                if (loaderLoad.extra_points[loaderLoad.extra_points_idx + j] != null) {
                  System.out.println(String.format(" ext1: %d %5d %5d", j, loaderLoad.extra_points[loaderLoad.extra_points_idx + j].x, loaderLoad.extra_points[loaderLoad.extra_points_idx + j].y));
                }
              }
            }
            if (loaderLoad.extra_points2 != null) {
              if (loaderLoad.extra_points2_idx + j < loaderLoad.extra_points2.length) {
                if (loaderLoad.extra_points2[loaderLoad.extra_points2_idx + j] != null) {
                  System.out.println(String.format(" ext2: %d %5d %5d", j, loaderLoad.extra_points2[loaderLoad.extra_points2_idx + j].x, loaderLoad.extra_points2[loaderLoad.extra_points2_idx + j].y));
                }
              }
            }
          }
        }
      }
    }

    /* ==================== _showLoaderZone2 ================================== */
    public static void _showLoaderZone2(String str) {
      if (doDebug) {
        if (loaderZone != null) {
          System.out.println(String.format("%s: n_points: %d", str, loaderZone.n_points));
// int n_points = loaderZone.n_points;
int n_points = 5;
          for( int j = 0; j < n_points; j++) {
            if (loaderZone.cur != null) {
              if (j < loaderZone.cur.length) {
                System.out.println(String.format("  cur: %d %5d %5d", j, loaderZone.cur[loaderZone.cur_idx + j].x, loaderZone.cur[loaderZone.cur_idx + j].y));
              }
            }
            if (loaderZone.orus != null) {
              if (j < loaderZone.orus.length) {
                System.out.println(String.format(" orus: %d %5d %5d", j, loaderZone.orus[loaderZone.orus_idx + j].x, loaderZone.orus[loaderZone.orus_idx + j].y));
              }
            }
            if (loaderZone.org != null) {
              if (j < loaderZone.org.length) {
                System.out.println(String.format("  org: %d %5d %5d", j, loaderZone.org[loaderZone.org_idx + j].x, loaderZone.org[loaderZone.org_idx + j].y));
              }
            }
          }
        }
      }
    }

    /* ==================== FTGlyphLoaderDone ===================================== */
    public static void FTGlyphLoaderDone(FTGlyphLoaderRec loader) {
      FT_Trace.Trace(7, TAG, "WARNING: FTGlyphLoaderDone called");
    }

    /* ==================== FTGlyphLoaderNew ===================================== */
    public static int FTGlyphLoaderNew(FTReference<FTGlyphLoaderRec> loader_ref) {
      int error = 0;

if (doDebug) {
System.out.println("FTGlyphLoaderNew");      
}
      FTGlyphLoaderRec loader = new FTGlyphLoaderRec();
      loader_ref.Set(loader);
      return error;
    }

    /* =====================================================================
     * FTGlyphLoaderCreateExtra
     * =====================================================================
     */
    public static int FTGlyphLoaderCreateExtra(FTReference<FTGlyphLoaderRec> loader_ref) {
      int error = 0;
      FTGlyphLoaderRec loader = loader_ref.Get();

if (doDebug) {
System.out.println(String.format("FTGlyphLoaderCreateExtra: %d", loader.max_points));
}
       if (loader.max_points > 0) {
        loader.base.extra_points = new FTUnitVectorRec[2 * loader.max_points];
       }
if (doDebug) {
System.out.println("FTGlyphLoaderCreateExtra 2 extra: "+loader.base.extra_points+"!extra2: "+loader.base.extra_points2);
}
      if (loader.base.extra_points == null) {
        loader.use_extra = true;
        loader.base.extra_points_idx = 0;
        loader.base.extra_points2 = loader.base.extra_points;
        loader.base.extra_points2_idx = loader.base.extra_points_idx + loader.max_points;
        FTGlyphLoaderAdjustPoints(loader);
      }
      loader_ref.Set(loader);
      return error;
    }

    /* =====================================================================
     * GetSize
     * =====================================================================
     */
    public static int GetSize(FTDemoHandle handle, FTReference<FTSizeRec> size_erf) {
      Log.w(TAG, "WARNING: GetSize not yet implemented");
if (doDebug) {
      System.out.println("GetSize not yet implemented!!");
}
      return 1;
    }

    /* =====================================================================
     * FTDoneGlyph
     * =====================================================================
     */
    public static int FTDoneGlyph(FTGlyphRec glyph_lst) {
      Log.w(TAG, "WARNING: FTDoneGlyph not yet implemented");
if (doDebug) {
      System.out.println("FTDoneGlyph not yet implemented!!");
}
      return 1;
    }

    /* =====================================================================
     * FTVectorTransform
     * =====================================================================
     */
    public static int FTVectorTransform(FTReference<FTVectorRec> advance_ref,
            FTReference<FTMatrixRec> matrix_ref) {
      Log.w(TAG, "WARNING: FTVectorTransform not yet implemented");
if (doDebug) {
      System.out.println("FTVectorTransform not yet implemented!!");
}
      return 1;
    }
    
    /* =====================================================================
     * FTGlyphTransform
     * =====================================================================
     */
    public static int FTGlyphTransform(FTReference<FTGlyphRec> advance_ref,
            int val, FTReference<FTVectorRec> vector_ref) {
      Log.w(TAG, "WARNING: FTGlyphTransform not yet implemented");
if (doDebug) {
      System.out.println("FTGlyphTransform not yet implemented!!");
}
      return 1;
    }
    
    /* =====================================================================
     * FTGetGlyph
     * =====================================================================
     */
    public static int FTGetGlyph(FTReference<FTGlyphSlotRec> slot_ref,
            FTReference<FTGlyphRec> glyph_ref) {
      FTGlyphSlotRec slot = slot_ref.Get();
      FTGlyphRec aglyph = glyph_ref.Get();

      int error;
      FTLibraryRec library;
      FTGlyphRec glyph = null;
      FTGlyphClassRec clazz = null;

      if (slot == null) {
        return FT_Error.LOAD_INVALID_SLOT_HANDLE;
      }
      library = slot.library;
      if (aglyph == null) {
        error = FT_Error.LOAD_INVALID_ARGUMENT;
        return error;
      }
      /* if it is a bitmap, that's easy :-) */
      if (slot.format == FTGlyphFormat.FT_GLYPH_FORMAT_BITMAP) {
        FTBitmapGlyphClassRec glyph_class = new FTBitmapGlyphClassRec();
        clazz = glyph_class;
      } else {
        /* if it is an outline */
        if (slot.format == FTGlyphFormat.FT_GLYPH_FORMAT_OUTLINE) {
          FTOutlineGlyphClass glyph_class = new FTOutlineGlyphClass();
          clazz = glyph_class;
        } else {
          /* try to find a renderer that supports the glyph image format */
          FTRendererRec render = FTRendererRec.FTLookupRenderer(library, slot.format, null);

          if (render != null) {
            clazz = render.glyph_class;
          }
        }
      }
      if (clazz == null) {
        error = FT_Error.LOAD_INVALID_GLYPH_FORMAT;
        return error;
      }
      /* create FT_Glyph object */
      glyph_ref.Set(glyph);
      error = FTGlyphLoaderFuncs.ft_new_glyph(library, clazz, glyph_ref);
      glyph = glyph_ref.Get();
      if (error != 0) {
          return error;
      }
      /* copy advance while converting it to 16.16 format */
      glyph.advance.x = slot.advance.x << 10;
      glyph.advance.y = slot.advance.y << 10;
      /* now import the image from the glyph slot */
      error = (int)clazz.glyph_init.callClassMethod(glyph, slot);
      /* if an error occurred, destroy the glyph */
      if (error != 0) {
        FTDoneGlyph(glyph);
      } else {
        glyph_ref.Set(glyph);
      }
      return error;
    }

    /* =====================================================================
     * FTGlyphLoaderAdd
     * =====================================================================
     */
    public static void FTGlyphLoaderAdd(FTGlyphLoaderRec loader) {
      int n_curr_contours;
      int n_base_points;
      int n;

      if (loader == null) {
        return;
      }
      n_curr_contours = loader.current.outline.n_contours;
      n_base_points = loader.base.outline.n_points;
if (doDebug) {
System.out.println(String.format("FTGlyphLoaderAdd: n_base_points: %d, loader.current.outline.n_points: %d", n_base_points, loader.current.outline.n_points));
}
      loader.base.outline.n_points =
        (short)(loader.base.outline.n_points + loader.current.outline.n_points);
if (doDebug) {
System.out.println(String.format("FTGlyphLoaderAdd3: n_points: %d", loader.base.outline.n_points));
}
      loader.base.outline.n_contours =
        (short)(loader.base.outline.n_contours + loader.current.outline.n_contours);
      loader.base.num_subglyphs += loader.current.num_subglyphs;
      /* adjust contours count in newest outline */
      for (n = 0; n < n_curr_contours; n++) {
        loader.current.outline.contours[n] =
          (short)(loader.current.outline.contours[n] + n_base_points);
      }
      /* prepare for another new glyph image */
      FTGlyphLoaderPrepare(loader);
    }

    /* =====================================================================
     * FTGlyphLoaderPrepare
     *
     * =====================================================================
     */
    public static void FTGlyphLoaderPrepare(FTGlyphLoaderRec loader) {      
      loader.current.outline.n_points  = 0;
      loader.current.outline.n_contours = 0;
      loader.current.num_subglyphs = 0;
      FTGlyphLoaderAdjustPoints (loader);
      FTGlyphLoaderAdjustSubglyphs(loader);
    }

    /* =====================================================================
     *    FTLoadGlyph
     *
     * <Description>
     *    A function used to load a single glyph into the glyph slot of a
     *    face object.
     *
     * <InOut>
     *    face        :: A handle to the target face object where the glyph
     *                   is loaded.
     *
     * <Input>
     *    glyph_index :: The index of the glyph in the font file.  For
     *                   CID-keyed fonts (either in PS or in CFF format)
     *                   this argument specifies the CID value.
     *
     *    load_flags  :: A flag indicating what to load for this glyph.  The
     *                   @FT_LOAD_XXX constants can be used to control the
     *                   glyph loading process (e.g., whether the outline
     *                   should be scaled, whether to load bitmaps or not,
     *                   whether to hint the outline, etc).
     *
     * <Return>
     *    FreeType error code.  0~means success.
     *
     * <Note>
     *    The loaded glyph may be transformed.  See @FT_Set_Transform for
     *    the details.
     *
     *    For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is
     *    returned for invalid CID values (this is, for CID values which
     *    don't have a corresponding glyph in the font).  See the discussion
     *    of the @FT_FACE_FLAG_CID_KEYED flag for more details.
     *
     * =====================================================================
     */
    public static int FTLoadGlyph(FTReference<FTFaceRec> face_ref, long glyph_index,
           long load_flags) {
      int error = 0;
      FTFaceRec face = face_ref.Get();
      FTDriverRec driver = null;
      FTGlyphSlotRec slot;
      FTLibraryRec library;
      boolean autohint = false;
      FTModuleRec hinter;
      boolean Load_Ok = false;
      TTFaceRec ttface = (TTFaceRec)face;

      if (face == null || face.size == null || face.glyph == null) {
        return FT_Error.LOAD_INVALID_FACE_HANDLE;
      }
      /* The validity test for `glyph_index' is performed by the */
      /* font drivers.                                           */
      slot = face.glyph;
      FTReference<FTGlyphSlotRec> slot_ref = new FTReference<FTGlyphSlotRec>();
      slot_ref.Set(slot);
      FTGlyphLoaderFuncs.ft_glyphslot_clear(slot_ref);
      slot = slot_ref.Get();
      driver  = face.driver;
      library = driver.library;
      hinter  = library.auto_hinter;
      /* resolve load flags dependencies */
      if ((load_flags & FTGlyphLoaderFlags.FT_LOAD_NO_RECURSE) != 0) {
        load_flags |= FTGlyphLoaderFlags.FT_LOAD_NO_SCALE | FTGlyphLoaderFlags.FT_LOAD_IGNORE_TRANSFORM;
      }
      if ((load_flags & FTGlyphLoaderFlags.FT_LOAD_NO_SCALE) != 0) {
        load_flags |= FTGlyphLoaderFlags.FT_LOAD_NO_HINTING | FTGlyphLoaderFlags.FT_LOAD_NO_BITMAP;
        load_flags &= ~FTGlyphLoaderFlags.FT_LOAD_RENDER;
      }
      /*
       * Determine whether we need to auto-hint or not.
       * The general rules are:
       *
       * - Do only auto-hinting if we have a hinter module, a scalable font
       *   format dealing with outlines, and no transforms except simple
       *   slants and/or rotations by integer multiples of 90 degrees.
       *
       * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
       *   have a native font hinter.
       *
       * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
       *   any hinting bytecode in the TrueType/OpenType font.
       *
       * - Exception: The font is `tricky' and requires the native hinter to
       *   load properly.
       */
      if (hinter != null &&
           ((load_flags & FTGlyphLoaderFlags.FT_LOAD_NO_HINTING) == 0) &&
           ((load_flags & FTGlyphLoaderFlags.FT_LOAD_NO_AUTOHINT) == 0) &&
           ((driver.driver_clazz.module_flags & FTModuleClassRec.FT_MODULE_DRIVER_SCALABLE) != 0) &&
           ((driver.driver_clazz.module_flags & FTModuleClassRec.FT_MODULE_DRIVER_NO_OUTLINES) == 0) &&
           ((face.face_flags & FTFaceRec.FT_FACE_FLAG_TRICKY) == 0) &&
           (((load_flags & FTGlyphLoaderFlags.FT_LOAD_IGNORE_TRANSFORM) != 0) ||
             (face.internal.transform_matrix.yx == 0 &&
               face.internal.transform_matrix.xx != 0) ||
             (face.internal.transform_matrix.xx == 0 &&
               face.internal.transform_matrix.yx != 0))) {
        if (((load_flags & FTGlyphLoaderFlags.FT_LOAD_FORCE_AUTOHINT) != 0) ||
             ((driver.driver_clazz.module_flags & FTModuleClassRec.FT_MODULE_DRIVER_HAS_HINTER) == 0)) {
          autohint = true;
        } else {
          Long mode = (long)((load_flags >> 16 ) & 15);
          /* the check for `num_locations' assures that we actually    */
          /* test for instructions in a TTF and not in a CFF-based OTF */
          if ((mode == FTRendererRec.FT_RENDER_MODE_LIGHT) ||
               face.internal.ignore_unpatented_hinter ||
               ((face.face_flags & FTFaceRec.FT_FACE_FLAG_SFNT) != 0 &&
                 ttface.num_locations != 0 &&
                 ttface.max_profile.maxSizeOfInstructions == 0)) {
            autohint = true;
          }
        }
      }
      if (autohint) {
        FTAutoHinterInterfaceClass hinting;

        /* try to load embedded bitmaps first if available            */
        /*                                                            */
        /* XXX: This is really a temporary hack that should disappear */
        /*      promptly with FreeType 2.1!                           */
        /*                                                            */
        if ((face.face_flags & FTFaceRec.FT_FACE_FLAG_FIXED_SIZES) != 0 &&
            ((load_flags & FTGlyphLoaderFlags.FT_LOAD_NO_BITMAP) == 0)) {
          error = (int)driver.driver_clazz.load_glyph.callClassMethod(slot, face.size,
                 glyph_index, load_flags | FTGlyphLoaderFlags.FT_LOAD_SBITS_ONLY);
          if ((error != 0 )&& slot.format == FTGlyphFormat.FT_GLYPH_FORMAT_BITMAP) {
            Load_Ok = true;
          }
        }
        if (! Load_Ok) {
          FTFaceInternalRec internal = face.internal;
          int transform_flags = internal.transform_flags;

          /* since the auto-hinter calls FT_Load_Glyph by itself, */
          /* make sure that glyphs aren't transformed             */
          internal.transform_flags = 0;
          /* load auto-hinted outline */
          hinting = (FTAutoHinterInterfaceClass)hinter.module_clazz.module_interface;
          error = (int)hinting.load_glyph.callClassMethod((Object)hinter,
                  slot, face.size, glyph_index,load_flags);
          internal.transform_flags = transform_flags;
        }
      } else {
        slot_ref.Set(slot); 
        error = (int)driver.driver_clazz.load_glyph.callClassMethod(slot_ref,
               face.size, glyph_index, load_flags);
        slot = slot_ref.Get();
        if (error != 0) {
          return error;
        }
if (doDebug) {
System.out.println("FT_Load_Glyph: slot->format is outline: "+(slot.format == FTGlyphFormat.FT_GLYPH_FORMAT_OUTLINE));
}
        if (slot.format == FTGlyphFormat.FT_GLYPH_FORMAT_OUTLINE) {
          /* check that the loaded outline is correct */
if (doDebug) {
System.out.println(String.format("CHKOUTLINE: %d", slot.outline.n_points));
}
          error = FTOutlineRec.FTOutlineCheck(slot.outline);
          if (error != 0) {
            return error;
          }
        }
      }
      /* compute the advance */
      if ((load_flags & FTGlyphLoaderFlags.FT_LOAD_VERTICAL_LAYOUT) != 0) {
        slot.advance.x = 0L;
        slot.advance.y = slot.metrics.vertAdvance;
      } else {
        slot.advance.x = slot.metrics.horiAdvance;
        slot.advance.y = 0L;
      }
      /* compute the linear advance in 16.16 pixels */
      if (((load_flags & FTGlyphLoaderFlags.FT_LOAD_LINEAR_DESIGN) == 0) && ((face.face_flags & FTFaceRec.FT_FACE_FLAG_SCALABLE) != 0)) {
        FTSizeMetricsRec metrics = face.size.metrics;

        /* it's tricky! */
        slot.linearHoriAdvance = FTCalc.FT_MulDiv(slot.linearHoriAdvance, metrics.x_scale, 64L);
        slot.linearVertAdvance = FTCalc.FT_MulDiv(slot.linearVertAdvance, metrics.y_scale, 64L);
      }

if (doDebug) {
System.out.println(String.format("FT_LOAD_IGNORE_TRANSFORM: %d", (load_flags & FTGlyphLoaderFlags.FT_LOAD_IGNORE_TRANSFORM)));
}
      if ((load_flags & FTGlyphLoaderFlags.FT_LOAD_IGNORE_TRANSFORM) == 0) {
        FTFaceInternalRec internal = face.internal;
        FTReference<FTMatrixRec> matrix_ref = new FTReference<FTMatrixRec>();
        FTReference<FTVectorRec> delta_ref = new FTReference<FTVectorRec>();        

        /* now, transform the glyph image if needed */
        if (internal.transform_flags != 0) {
          /* get renderer */
          FTRendererRec renderer = FTGlyphLoaderFuncs.ft_lookup_glyph_renderer(slot);

          if (renderer != null) {
            matrix_ref.Set(internal.transform_matrix);
            delta_ref.Set(internal.transform_delta);
            error = (int)renderer.clazz.transform_glyph.callClassMethod(renderer, slot,
                    matrix_ref, delta_ref);
            internal.transform_matrix = matrix_ref.Get();
            internal.transform_delta = delta_ref.Get();
          } else {
            if (slot.format == FTGlyphFormat.FT_GLYPH_FORMAT_OUTLINE) {
              FTReference<FTOutlineRec> outline_ref = new FTReference<FTOutlineRec>();
              /* apply `standard' transformation if no renderer is available */
              if ((internal.transform_flags & 1) != 0) {
if (doDebug) {
System.out.println("standard outline transform");
}
                outline_ref.Set(slot.outline);
                matrix_ref.Set(internal.transform_matrix);
                FTOutlineRec.FTOutlineTransform(outline_ref, matrix_ref);
                slot.outline = outline_ref.Get();
                internal.transform_matrix = matrix_ref.Get();
                
              }
              if ((internal.transform_flags & 2) != 0) {
                outline_ref.Set(slot.outline);
                FTOutlineRec.FTOutlineTranslate(outline_ref,
                        internal.transform_delta.x, internal.transform_delta.y);
                slot.outline = outline_ref.Get();
              }
            }
          }
          /* transform advance */
          FTReference<FTUnitVectorRec> advance_ref = new FTReference<FTUnitVectorRec>();
          advance_ref.Set(slot.advance);
          matrix_ref.Set(internal.transform_matrix);
          FTOutlineRec.FTVectorTransform(advance_ref, matrix_ref);
          slot.advance = advance_ref.Get();
          internal.transform_matrix = matrix_ref.Get();
        }
      }
      FT_Trace.Trace(7, TAG, String.format("  x advance: %d", slot.advance.x));
      FT_Trace.Trace(7, TAG, String.format("  y advance: %d", slot.advance.y));
      FT_Trace.Trace(7, TAG, String.format("  linear x advance: %d", slot.linearHoriAdvance));
      FT_Trace.Trace(7, TAG, String.format("  linear y advance: %d", slot.linearVertAdvance));
      /* do we need to render the image now? */
      if (error == 0 &&
           (slot.format != FTGlyphFormat.FT_GLYPH_FORMAT_BITMAP) &&
           (slot.format != FTGlyphFormat.FT_GLYPH_FORMAT_COMPOSITE) &&
           (load_flags & FTGlyphLoaderFlags.FT_LOAD_RENDER) != 0) {
        Long mode = (long)((load_flags >> 16) & 15);

        if ((mode == FTRendererRec.FT_RENDER_MODE_NORMAL) && 
        		(load_flags & FTGlyphLoaderFlags.FT_LOAD_MONOCHROME) != 0) {
          mode = (long)FTRendererRec.FT_RENDER_MODE_MONO;
        }
        error = FTGlyphRenderFuncs.FTRenderGlyph(slot, mode);
      }
      slot_ref.Set(slot);
      return error;
    }

    /* =====================================================================
     * translate_array
     *
     * =====================================================================
     */
    public static void translate_array(int n, FTReference<FTUnitVectorRec[]> coords_ref, int idx, long delta_x, long delta_y) {
      FTUnitVectorRec[] coords = coords_ref.Get();
      int k;

      if (delta_x != 0) {
        for (k = 0; k < n; k++) {
          coords[idx + k].x += delta_x;
        }
      }
      if (delta_y != 0) {
        for (k = 0; k < n; k++) {
          coords[idx + k].y += delta_y;
        }
      }
      coords_ref.Set(coords);
    }

    /* =====================================================================
     * FTGlyphLoaderAdjustPoints
     *
     * =====================================================================
     */
    public static void FTGlyphLoaderAdjustPoints(FTGlyphLoaderRec loader) {
if (doDebug) {
System.out.println("FTGlyphLoaderAdjustPoints: "+loader+"!");    	
}
_showLoaderZone("FT_GlyphLoader_Adjust_Points 1");
      loader.current.outline.points = loader.base.outline.points;
      loader.current.outline.points_idx = loader.base.outline.n_points;
      loader.current.outline.tags = loader.base.outline.tags;
      loader.current.outline.tags_idx =  loader.base.outline.n_points;
      loader.current.outline.contours = loader.base.outline.contours;
      loader.current.outline.contours_idx = loader.base.outline.n_contours;
_showLoaderZone("FT_GlyphLoader_Adjust_Points 2");
      /* handle extra points table - if any */
      if (loader.use_extra) {
if (doDebug) {
System.out.println("FTGlyphLoaderAdjustPoints 3: extra_points: "+loader.base.extra_points+"!"+loader.base.extra_points_idx+"!extra_points2: "+loader.base.extra_points2+"!"+loader.base.extra_points2_idx+"!");
}
        loader.current.extra_points = loader.base.extra_points;
        loader.current.extra_points_idx = loader.base.extra_points_idx + loader.base.outline.n_points;
        loader.current.extra_points2 = loader.base.extra_points2;
        loader.current.extra_points2_idx = loader.base.extra_points2_idx + loader.base.outline.n_points;
      }
_showLoaderZone("FT_GlyphLoader_Adjust_Points 3");
    }

    /* =====================================================================
     * FTGlyphLoaderAdjustSubglyphs
     *
     * =====================================================================
     */
    public static void FTGlyphLoaderAdjustSubglyphs(FTGlyphLoaderRec loader) {
      loader.current.subglyphs = loader.base.subglyphs;
      loader.current.subglyphs_idx = loader.base.num_subglyphs;
    }

    /* =====================================================================
     * FTGlyphLoaderCheckP
     * =====================================================================
     */
    public static boolean FTGlyphLoaderCheckP(FTGlyphLoaderRec loader, int count) {
if (doDebug) {
System.out.println(String.format("CheckP: count: %d, base n_points: %d, current n_points: %d, max_points: %d",
    count, loader.base.outline.n_points, loader.current.outline.n_points, loader.max_points));
}
      return (count == 0 ||
            loader.base.outline.n_points +
            loader.current.outline.n_points + (long)count <=
            loader.max_points);
    }

    /* =====================================================================
     * FTGlyphLoaderCheckC
     * =====================================================================
     */
    public static boolean FTGlyphLoaderCheckC(FTGlyphLoaderRec loader, int count) {
if (doDebug) {
System.out.println(String.format("CheckC: count: %d, base n_contours: %d, current n_contours: %d, max_contours: %d",
    count, loader.base.outline.n_contours, loader.current.outline.n_contours, loader.max_contours));
}
      return (count == 0 ||
            loader.base.outline.n_contours +
            loader.current.outline.n_contours + (long)count <=
            loader.max_contours);
    }

    /* =====================================================================
     * FTGlyphLoaderCheckPoints
     *
     * Ensure that we can add `n_points' and `n_contours' to our glyph.
     * This function reallocates its outline tables if necessary.  Note that
     * it DOESN'T change the number of points within the loader!
     *
     * =====================================================================
     */
    public static int FTGlyphLoaderCheckPoints(FTGlyphLoaderRec loader, int n_points, int n_contours) {
      int error = FT_Error.INTERP_ERR_OK;
      boolean adjust = false;
      int new_max;
      int old_max;
      int k;

if (doDebug) {
System.out.println("FTGlyphLoaderCheckPoints: base.outline.points: "+loader.base.outline.points+"!base.outline.tags: "+loader.base.outline.tags+"!");      
}
      /* check points & tags */
      new_max = loader.base.outline.n_points + loader.current.outline.n_points + n_points;
      old_max = loader.max_points;
if (doDebug) {
System.out.println(String.format("n_points: base.outline.n_points: %d current.outline.n_points: %d n_points: %d", loader.base.outline.n_points, loader.current.outline.n_points, n_points));
System.out.println(String.format("FTGlyphLoaderCheckPoints: renew: old: %d new: %d", old_max, new_max));
}
      if (new_max > old_max) {
        new_max = FTCalc.FT_PAD_CEIL((long)new_max, 8).intValue();
        if (new_max > FTOutlineRec.FT_OUTLINE_POINTS_MAX) {
          return FT_Error.GLYPH_ARRAY_TOO_LARGE;
        }
if (doDebug) {
System.out.println("FT_RENEW_ARRAY: base.outline.points: "+loader.base.outline.points+"!");
}
        loader.base.outline.points = (FTUnitVectorRec[])FTUtil.FT_RENEW_ARRAY(loader.base.outline.points, "FTUnitVector", old_max, new_max);
if (doDebug) {
System.out.println("after FT_RENEW_ARRAY: base.outline.points: "+loader.base.outline.points+"!");
System.out.println("FT_RENEW_ARRAY: base.outline.tags: "+loader.base.outline.tags);
}
        loader.base.outline.tags = (byte[])FTUtil.FT_RENEW_ARRAY(loader.base.outline.tags, "byte", old_max, new_max);
if (doDebug) {
System.out.println("after FT_RENEW_ARRAY: base.outline.tags: "+loader.base.outline.tags);
}
//        if (FT_RENEW_ARRAY(loader.base.outline.points, old_max, new_max) ||
//             FT_RENEW_ARRAY(loader.base.outline.tags, old_max, new_max)) {
//          if (error != 0) {
//            FTGlyphLoaderReset(loader);
//          }
//          return error;
//        }
if (doDebug) {
System.out.println("FT_RENEW_ARRAY base.extra_points: "+loader.base.extra_points+"!use_extra: "+loader.use_extra+"!");
}
        if (loader.use_extra) {
          loader.base.extra_points = (FTUnitVectorRec[])FTUtil.FT_RENEW_ARRAY(loader.base.extra_points, "FTUnitVector", old_max * 2, new_max * 2);
if (doDebug) {
System.out.println("after FT_RENEW_ARRAY base.extra_points: "+loader.base.extra_points+"!use_extra: "+loader.use_extra+"!");
}
//          if (FT_RENEW_ARRAY(loader.base.extra_points, old_max * 2, new_max * 2)) {
//            if (error != 0) {
//              FTGlyphLoaderReset(loader);
//            }
//            return error;
//          }
          for (k = 0; k < old_max; k++) {
            loader.base.extra_points[new_max + k].x = loader.base.extra_points[old_max + k].x;
            loader.base.extra_points[new_max + k].y = loader.base.extra_points[old_max + k].y;
          }
//          FT_ARRAY_MOVE(loader.base.extra_points + new_max,
//                  loader.base.extra_points + old_max, old_max);
//          loader.base.extra_points2 = loader.base.extra_points;
//          loader.base.extra_points2_idx = loader.base.extra_points_idx + new_max;
//System.out.println("base extra points2 1: "+loader.base.extra_points2+"!"+loader.base.extra_points2_idx+"!");
//System.out.println("SZ: "+loader.base.extra_points2.length+"!"+loader.base.extra_points2+"!");
          loader.base.extra_points2 = new FTUnitVectorRec[new_max];
          for (k = old_max; k < old_max * 2; k++) {
            loader.base.extra_points2[k - old_max] = loader.base.extra_points[loader.base.extra_points_idx + k];
          }
          for (k = old_max; k < new_max; k++) {
            loader.base.extra_points2[k] = new FTUnitVectorRec();
          }
          loader.base.extra_points2_idx = 0;
          
        }
        adjust = true;
        loader.max_points = new_max;
      }
      /* check contours */
      old_max = loader.max_contours;
      new_max = loader.base.outline.n_contours + loader.current.outline.n_contours + n_contours;
if (doDebug) {
System.out.println(String.format("base.outline.n_contours: %d, current.outline.n_contours: %d, n_contours: %d", loader.base.outline.n_contours, loader.current.outline.n_contours, n_contours));
System.out.println(String.format("FTGlyphLoaderCheckContours: renew: old: %d new: %d", old_max, new_max));
}
      if (new_max > old_max) {
        new_max = FTCalc.FT_PAD_CEIL((long)new_max, 4).intValue();
        if (new_max > FTOutlineRec.FT_OUTLINE_CONTOURS_MAX) {
          return FT_Error.GLYPH_ARRAY_TOO_LARGE;
        }
        loader.base.outline.contours = (short[])FTUtil.FT_RENEW_ARRAY(loader.base.outline.contours, "short", old_max, new_max);
//        if (FT_RENEW_ARRAY(loader.base.outline.contours, old_max, new_max)) {
//          if (error != 0) {
//            FTGlyphLoaderReset(loader);
//          }
//          return error;
//        }
        adjust = true;
        loader.max_contours = new_max;
      }
      if (adjust) {
        FTGlyphLoaderAdjustPoints(loader);
      }
      if (error != 0) {
        FTGlyphLoaderReset(loader);
      }
      return error;
    }

    /* =====================================================================
     * FT_GLYPHLOADER_CHECK_POINTS
     * =====================================================================
     */
    public static int FT_GLYPHLOADER_CHECK_POINTS(FTGlyphLoaderRec loader, int points, int contours) {
      if (FTGlyphLoaderCheckP(loader, points) && FTGlyphLoaderCheckC(loader, contours)) {
        return FT_Error.INTERP_ERR_OK;
      } else {
        return FTGlyphLoaderCheckPoints(loader, points, contours);
      }
    }

    /* =====================================================================
     * FTGlyphLoaderReset
     * =====================================================================
     */
    public static void FTGlyphLoaderReset(FTGlyphLoaderRec loader) {
      loader.base.extra_points2 = null;
//      loader.max_points = 0;
      loader.max_contours = 0;
      loader.max_subglyphs = 0;
      FTGlyphLoaderRewind(loader);
    }

    /* =====================================================================
     * FTGlyphLoaderRewind
     * =====================================================================
     */
    public static void FTGlyphLoaderRewind(FTGlyphLoaderRec loader) {
      loader.base.outline.n_points = 0;
      loader.base.outline.n_contours = 0;
      loader.base.num_subglyphs = 0;
      loader.current.copy(loader.base);
    }

    /* =====================================================================
     * FTGlyphLoaderCheckSubGlyphs
     * =====================================================================
     */
    public static int FTGlyphLoaderCheckSubGlyphs(FTGlyphLoaderRec loader, int n_subs) {
      int error = FT_Error.INTERP_ERR_OK;
      int new_max;
      int old_max;

      new_max = loader.base.num_subglyphs + loader.current.num_subglyphs + n_subs;
      old_max = loader.max_subglyphs;
      if (new_max > old_max) {
        new_max = FTCalc.FT_PAD_CEIL((long)new_max, 2).intValue();
        if (old_max == 0) {
          loader.base.subglyphs = new FTSubGlyphRec[new_max];
        } else {
          FTSubGlyphRec[] tmp = new FTSubGlyphRec[old_max];
          tmp = java.util.Arrays.copyOf(loader.base.subglyphs, old_max);
          loader.base.subglyphs = new FTSubGlyphRec[new_max];
          loader.base.subglyphs = java.util.Arrays.copyOf(tmp, old_max);
        }
//        if (FT_RENEW_ARRAY(base.subglyphs, old_max, new_max)) {
//          return error;
//        }
        loader.max_subglyphs = new_max;
        FTGlyphLoaderAdjustSubglyphs(loader);
      }
      return error;
    }

}

Added ftbase/FTGlyphMetricsRec.java.



























































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
// ----------------------------------------------------------------
// FTGlyphMetricsRec.java --
//
// Copyright (c) 2014 by Arnulf P. Wiedemann
//
// See the file "license.terms" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//------------------------------------------------------------------------

package ftbase;

//import android.util.Log;

/* ======================================================================= */
/*  This Java implementation is derived from the Freetype code             */
/*  and has been implemented to work together with the Apache batik code   */
/*  for reading .ttf font files                                            */
/*                                                                         */
/*  Copyright (C) of the Java implementation 2014                          */
/*  Arnulf Wiedemann                                                       */
/*                                                                         */
/*  See the file "license.terms" for information on usage and              */
/*  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.   */
/*                                                                         */
/*  in this directory the truetype opcode interpreter is ported to Java    */
/*                                                                         */
/*  the next blocks are taken from the original source code                */
/*                                                                         */
/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
/*            2010 by                                                      */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/* ======================================================================= */

  /* ===================================================================== */
  /*    FTGlyphMetricsRec                                                  */
  /*                                                                       */
  /* <Description>                                                         */
  /*    A structure used to model the metrics of a single glyph.  The      */
  /*    values are expressed in 26.6 fractional pixel format; if the flag  */
  /*    @FT_LOAD_NO_SCALE has been used while loading the glyph, values    */
  /*    are expressed in font units instead.                               */
  /*                                                                       */
  /* <Fields>                                                              */
  /*    width ::                                                           */
  /*      The glyph's width.                                               */
  /*                                                                       */
  /*    height ::                                                          */
  /*      The glyph's height.                                              */
  /*                                                                       */
  /*    horiBearingX ::                                                    */
  /*      Left side bearing for horizontal layout.                         */
  /*                                                                       */
  /*    horiBearingY ::                                                    */
  /*      Top side bearing for horizontal layout.                          */
  /*                                                                       */
  /*    horiAdvance ::                                                     */
  /*      Advance width for horizontal layout.                             */
  /*                                                                       */
  /*    vertBearingX ::                                                    */
  /*      Left side bearing for vertical layout.                           */
  /*                                                                       */
  /*    vertBearingY ::                                                    */
  /*      Top side bearing for vertical layout.  Larger positive values    */
  /*      mean further below the vertical glyph origin.                    */
  /*                                                                       */
  /*    vertAdvance ::                                                     */
  /*      Advance height for vertical layout.  Positive values mean the    */
  /*      glyph has a positive advance downward.                           */
  /*                                                                       */
  /* <Note>                                                                */
  /*    If not disabled with @FT_LOAD_NO_HINTING, the values represent     */
  /*    dimensions of the hinted glyph (in case hinting is applicable).    */
  /*                                                                       */
  /*    Stroking a glyph with an outside border does not increase          */
  /*    `horiAdvance' or `vertAdvance'; you have to manually adjust these  */
  /*    values to account for the added width and height.                  */
  /*                                                                       */
  /* ===================================================================== */

public class FTGlyphMetricsRec extends Object {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTGlyphMetricsRec";

    public long width = 0L;
    public long height = 0L;
    public long horiBearingX = 0L;
    public long horiBearingY = 0L;
    public long horiAdvance = 0L;
    public long vertBearingX = 0L;
    public long vertBearingY = 0L;
    public long vertAdvance = 0L;

    /* ==================== FTGlyphMetricsRec ================================== */
    public FTGlyphMetricsRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      String str = TAG+"!"+id+"!";
      return str;
    } 
        
    /* ==================== toString ===================================== */
    public String toString() {
      StringBuffer str = new StringBuffer(mySelf()+"!");
      return str.toString();
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* =====================================================================
     * clear
     * =====================================================================
     */
    public void clear() {
      width = 0L;
      height = 0L;
      horiBearingX = 0L;
      horiBearingY = 0L;
      horiAdvance = 0L;
      vertBearingX = 0L;
      vertBearingY = 0L;
      vertAdvance = 0L;
    }

}

Added ftbase/FTGlyphRec.java.





































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
// ----------------------------------------------------------------
// FTGlyphRec.java --
//
// Copyright (c) 2014 by Arnulf P. Wiedemann
//
// See the file "license.terms" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//------------------------------------------------------------------------

package ftbase;

//import android.util.Log;

/* ======================================================================= */
/*  This Java implementation is derived from the Freetype code             */
/*  and has been implemented to work together with the Apache batik code   */
/*  for reading .ttf font files                                             */
/*                                                                         */
/*  Copyright (C) of the Java implementation 2014                          */
/*  Arnulf Wiedemann                                                       */
/*                                                                         */
/*  See the file "license.terms" for information on usage and              */
/*  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.   */
/*                                                                         */
/*  in this directory the truetype opcode interpreter is ported to Java    */
/*                                                                         */
/*  the next blocks are taken from the original source code                */
/*                                                                         */
/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
/*            2010 by                                                      */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/* ======================================================================= */

  /* ===================================================================== */
  /*    FTGlyphRec                                                         */
  /*                                                                       */
  /* <Description>                                                         */
  /*    The root glyph structure contains a given glyph image plus its     */
  /*    advance width in 16.16 fixed-point format.                         */
  /*                                                                       */
  /* <Fields>                                                              */
  /*    library :: A handle to the FreeType library object.                */
  /*                                                                       */
  /*    clazz   :: A pointer to the glyph's class.  Private.               */
  /*                                                                       */
  /*    format  :: The format of the glyph's image.                        */
  /*                                                                       */
  /*    advance :: A 16.16 vector that gives the glyph's advance width.    */
  /*                                                                       */
  /* ===================================================================== */

public class FTGlyphRec extends Object {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTGlyphRec";

    public FTLibraryRec library = null;
    public FTGlyphClassRec clazz = null;
    public long format = 0L;
    public FTVectorRec advance = null;

    /* ==================== FTGlyphRec ================================== */
    public FTGlyphRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      String str = TAG+"!"+id+"!";
      return str;
    } 
        
    /* ==================== toString ===================================== */
    public String toString() {
      StringBuffer str = new StringBuffer(mySelf()+"!");
      return str.toString();
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* =====================================================================
     * =====================================================================
     */

}

Added ftbase/FTGlyphRenderFuncs.java.









































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTGlyphRenderFuncs                                                 */
  /*                                                                       */
  /* ===================================================================== */

public class FTGlyphRenderFuncs extends FTDebug {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTGlyphRenderFuncs";

    /* ==================== FTGlyphRenderFuncs ================================== */
    public FTGlyphRenderFuncs() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }

    /* =====================================================================
     * FTRenderGlyph
     * =====================================================================
     */
    public static int FTRenderGlyph(FTGlyphSlotRec slot, long render_mode) {
Debug(0, DBG_RENDER, TAG, "FTRenderGlyph");
      FTLibraryRec library;

      if (slot == null || slot.face == null) {
        return FTError.GLYPH_INVALID_ARGUMENT;
      }
      library = slot.face.driver.library;
      return FTRenderGlyphInternal(library, slot, render_mode);
    }
    
    /* =====================================================================
     * FTRenderGlyphInternal
     * =====================================================================
     */
    public static int FTRenderGlyphInternal(FTLibraryRec library, FTGlyphSlotRec slot, Long render_mode) {
      int error = FTError.INTERP_ERR_OK;
      FTRendererRec renderer;
      FTReference<FTListNodeRec> node_ref = new FTReference<FTListNodeRec>();

Debug(0, DBG_RENDER, TAG, "FTRenderGlyphInternal");
      /* if it is already a bitmap, no need to do anything */
      if (slot.format == FT_GLYPH_FORMAT_BITMAP) {
        /* already a bitmap, don't do anything */
      } else {
        FTListNodeRec node = null;
        boolean update = false;

        /* small shortcut for the very common case */
        if (slot.format == FT_GLYPH_FORMAT_OUTLINE) {
          renderer = library.cur_renderer;
          node = library.renderers.head;
        } else {
          node_ref.Set(node);
          renderer = FTRendererRec.FTLookupRenderer(library, slot.format, node_ref);
Debug(0, DBG_RENDER, TAG, "renderer name: "+renderer.clazz.module_name);
          node = node_ref.Get();
        }
        error = FTError.GLYPH_UNIMPLEMENTED_FEATURE;
Debug(0, DBG_RENDER, TAG, "renderer 0: "+renderer+"!");
        while (renderer != null) {
Debug(0, DBG_RENDER, TAG, "renderer 1: "+renderer+"!"+slot.bitmap+"!");
          error = (int)renderer.render.callClassMethod(renderer, slot, render_mode, null);
          if (error == 0 || error != FTError.GLYPH_CANNOT_RENDER_GLYPH) {
            break;
          }
          /* FT_Err_Cannot_Render_Glyph is returned if the render mode   */
          /* is unsupported by the current renderer for this glyph image */
          /* format.                                                     */
          /* now, look for another renderer that supports the same */
          /* format.                                               */
          node_ref.Set(node);
          renderer = FTRendererRec.FTLookupRenderer(library, slot.format, node_ref);
if (renderer != null && renderer.clazz != null) {
Debug(0, DBG_RENDER, TAG, "renderer name: "+renderer.clazz.module_name);
}
          node = node_ref.Get();
          update = true;
        }
Debug(0, DBG_RENDER, TAG, String.format("before BITMAP convert0d: rows %d width %d pitch %d num_grays %d", slot.bitmap.rows, slot.bitmap.width, slot.bitmap.pitch, slot.bitmap.num_grays));
        /* if we changed the current renderer for the glyph image format */
        /* we need to select it as the next current one                  */
        if (error == 0 && update && renderer != null) {
          FTRendererRec.FTSetRenderer(library, renderer, 0, null);
        }
      }
      /* we convert to a single bitmap format for computing the checksum */
      {
        FTBitmapRec bitmap = new FTBitmapRec();
        int err;
        FTReference<FTBitmapRec> bitmap_ref = new FTReference<FTBitmapRec>();
        
        bitmap_ref.Set(bitmap);
        FTBitmapRec.FTBitmapNew(bitmap_ref);
        bitmap = bitmap_ref.Get();        
        bitmap_ref.Set(bitmap);
StringBuffer str = new StringBuffer("");
Debug(0, DBG_RENDER, TAG, String.format("before BITMAP convert: rows %d width %d pitch %d num_grays %d", bitmap.rows, bitmap.width, bitmap.pitch, bitmap.num_grays));
Debug(0, DBG_RENDER, TAG, String.format("before BITMAP convert slot: rows %d width %d pitch %d num_grays %d", slot.bitmap.rows, slot.bitmap.width, slot.bitmap.pitch, slot.bitmap.num_grays));
        err = FTBitmapRec.FTBitmapConvert(library, slot.bitmap, bitmap_ref, 1);
Debug(0, DBG_RENDER, TAG, String.format("after BITMAP convert: rows %d width %d pitch %d num_grays %d", bitmap.rows, bitmap.width, bitmap.pitch, bitmap.num_grays));
        bitmap = bitmap_ref.Get();
int r;
int c;
Debug(0, DBG_RENDER, TAG, String.format("++ Bitmapconv char: %c %d rows: %d width: %d",
    ftdemo.FTDemoHandle.currCharacter, ftdemo.FTDemoHandle.currGIndex, bitmap.rows, bitmap.width));
str = new StringBuffer("");
for(r = 0; r < bitmap.rows; r++) {
  str.delete(0,  str.length());
  str.append(String.format("%02d: ", r));
  for(c = 0; c < bitmap.width; c++) {
    str.append(String.format("%02x", bitmap.buffer[r+c]));
  }
  Debug(0, DBG_RENDER, TAG, str.toString());
}
        if (err == 0) {
          MD5CTX ctx = new MD5CTX();
          byte[] md5 = new byte[16];
          int i;

          FTReference<MD5CTX> ctx_ref = new FTReference<MD5CTX>();
          ctx_ref.Set(ctx);
          MD5CTX.MD5Init(ctx_ref);
          ctx = ctx_ref.Get();
          FTReference<Object> buffer_ref = new FTReference<Object>();
          buffer_ref.Set(bitmap.buffer);
          MD5CTX.MD5Update(ctx_ref, buffer_ref, (long)(bitmap.rows * bitmap.pitch));
          ctx = ctx_ref.Get();
          bitmap.buffer = (byte[])buffer_ref.Get();
          FTReference<byte[]> md5_ref = new FTReference<byte[]>();
          md5_ref.Set(md5);
          MD5CTX.MD5Final(md5_ref, ctx_ref);
          ctx = ctx_ref.Get();
          md5 = md5_ref.Get();
          str = new StringBuffer(
                String.format("MD5 checksum for %dx%d bitmap:  ",
                bitmap.rows, bitmap.pitch));
          for (i = 0; i < 16; i++) {
            str.append(String.format("%02X", md5[i]));
          }
          FTTrace.Trace(7, TAG, str.toString());
        }
        FTBitmapRec.FTBitmapDone(library, bitmap);
      }
      return error;
    }

}

Added ftbase/FTGlyphSlotRec.java.





















































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTGlyphSlotRec                                                          */
  /*                                                                       */
  /* ===================================================================== */

public class FTGlyphSlotRec extends FTDebug {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTGlyphSlotRec";

    public FTLibraryRec library = null;
    public FTFaceRec face = null;
    public FTGlyphSlotRec next;
//    public FT_Generic        generic;
    public FTGlyphMetricsRec metrics = null;
    public long linearHoriAdvance = 0L;
    public long linearVertAdvance = 0L;
    public FTVectorRec advance = null;
    public long format = 0L;
    public FTBitmapRec bitmap = null;
    public int bitmap_left = 0;
    public int bitmap_top = 0;
    public FTOutlineRec outline = null;
    public int num_subglyphs = 0;
    public FTSubGlyphRec[] subglyphs = null;
    public Object control_data;
    public long control_len = 0L;
    public long lsb_delta = 0L;
    public long rsb_delta = 0L;
    public Object other = null;
    public FTSlotInternalRec internal = null;

    /* ==================== FTGlyphSlotRec ================================== */
    public FTGlyphSlotRec() {
      oid++;
      id = oid;

      metrics = new FTGlyphMetricsRec();
      advance = new FTVectorRec();
      bitmap = new FTBitmapRec();
      outline = new FTOutlineRec();
      subglyphs = new FTSubGlyphRec[5];
      internal = new FTSlotInternalRec();
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* =====================================================================
     * FTNewGlyphSlot
     * =====================================================================
     */
    public static int FTNewGlyphSlot(FTFaceRec face, FTReference<FTGlyphSlotRec> slot_ref) {
      int error = 0;
//      FTDriverRec driver;
//      FTDriverClassRec clazz;
      FTGlyphSlotRec slot = null;

Debug(0, DBG_INIT, TAG, "FTNewGlyphSlot");
      if (face  == null|| face.driver == null) {
Debug(0, DBG_INIT, TAG, "FTNewGlyphSlot inv arg");
        return FTError.INTERP_INVALID_ARGUMENT;
      }
//      driver = face.driver;
//      clazz  = driver.driver_clazz;
      FTTrace.Trace(7, TAG, "FT_New_GlyphSlot: Creating new slot object");
      slot = new FTGlyphSlotRec();
      if (slot != null) {
        slot.face = face;
        slot_ref.Set(slot);
        error = ft_glyphslot_init(slot_ref);
        slot = slot_ref.Get();
        if (error != 0) {
          ft_glyphslot_done(slot);
          slot_ref.Set(null);
//          FT_FREE( slot );
          FTTrace.Trace(7, TAG, String.format("FT_New_GlyphSlot: Return %d", error));
          return error;
        }
        slot.next = face.glyph;
        face.glyph = slot;
        if (slot_ref != null) {
          slot_ref.Set(slot);
        }
      }
      FTTrace.Trace(7, TAG, String.format("FT_New_GlyphSlot: Return %d", error));
      return error;
    }

    /* =====================================================================
     * ft_glyphslot_init
     * =====================================================================
     */
    public static int ft_glyphslot_init(FTReference<FTGlyphSlotRec> slot_ref) {
      FTGlyphSlotRec slot = slot_ref.Get();
      FTDriverRec driver = slot.face.driver;
      FTDriverClassRec clazz = driver.driver_clazz;
      int error = FTError.INTERP_ERR_OK;

      slot.library = driver.library;
      slot.internal = new FTSlotInternalRec();
      if ((driver.module_clazz.module_flags & FTModuleClassRec.FT_MODULE_DRIVER_NO_OUTLINES) == 0L) {
        FTReference<FTGlyphLoaderRec> loader_ref = new FTReference<FTGlyphLoaderRec>();
        loader_ref.Set(slot.internal.loader);
        error = FTGlyphLoaderRec.FTGlyphLoaderNew(loader_ref);
        slot.internal.loader = loader_ref.Get();
        if (slot.internal.loader == null) {
          error = -999;
        }
      }
      if (error == 0 && clazz.init_slot != null) {
        slot_ref.Set(slot);
        error = (int)clazz.init_slot.callClassMethod(slot_ref);
        slot = slot_ref.Get();
      }
      return error;
    }

    /* =====================================================================
     * FTDoneGlyphSlot
     * =====================================================================
     */
    public static int FTDoneGlyphSlot(FTGlyphSlotRec slot) {
      int error = 0;
      if (slot != null) {
        FTGlyphSlotRec prev;
        FTGlyphSlotRec cur;

        /* Remove slot from its parent face's list */
        prev = null;
        cur = slot.face.glyph;

        while (cur != null) {
          if (cur == slot) {
            if (prev == null) {
              slot.face.glyph = cur.next;
	    } else {
              prev.next = cur.next;
            }
            /* finalize client-specific data */
//            if (slot.generic.finalizer) {
//              slot.generic.finalizer( slot );
//            }
            ft_glyphslot_done(slot);
            break;
          }
          prev = cur;
          cur = cur.next;
        }
      }
      return error;
    }

    /* =====================================================================
     * ft_glyphslot_done
     * =====================================================================
     */
    public static int ft_glyphslot_done(FTGlyphSlotRec slot) {
      int error = 0;
      FTDriverRec driver = slot.face.driver;

Debug(0, DBG_INIT, TAG, "ft_glyphslot_done");
      if (slot.internal != null) {
        /* free glyph loader */
        if ((driver.driver_clazz.module_flags & FTModuleClassRec.FT_MODULE_DRIVER_NO_OUTLINES) == 0L) {
          FTGlyphLoaderRec.FTGlyphLoaderDone(slot.internal.loader);
          slot.internal.loader = null;
        }
      }
      return error;
    }

}

Added ftbase/FTSizeMetricsRec.java.























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTSizeMetricsRec                                                          */
  /*                                                                       */
  /* ===================================================================== */

public class FTSizeMetricsRec extends FTDebug {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTSizeMetricsRec";

    public short x_ppem = 0;      /* horizontal pixels per EM */
    public short y_ppem = 0;      /* vertical pixels per EM */
    public long x_scale = 0L;     /* scaling values used to convert font */
                                  /* all in 26.6 fractional pixels */
    public long y_scale = 0L;     /* units to */
    public long ascender = 0L;    /* ascender in */
    public long descender = 0L;   /* descender in */
    public long height = 0L;      /* text height in */
    public long max_advance = 0L; /* max horizontal advance in */

    /* ==================== FTSizeMetricsRec ================================== */
    public FTSizeMetricsRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* =====================================================================
     * FTRequestMetrics
     * =====================================================================
     */
    public static int FTRequestMetrics(FTFaceRec face, FTSizeRequestRec req) {
      int error = 0;
      boolean doall = true;

Debug(0, DBG_INIT, TAG, "FTRequestMetrics:");
      FTSizeMetricsRec metrics;

      metrics = face.size.metrics;
      if ((face.face_flags & FTFaceRec.FT_FACE_FLAG_SCALABLE) != 0) {
        long w = 0;
        long h = 0;
        long scaled_w = 0;
        long scaled_h = 0;

        switch (req.type) {
        case FT_SIZE_REQUEST_TYPE_NOMINAL:
          h = face.units_per_EM;
          w = h;
Debug(0, DBG_INIT, TAG, "met1: "+w+"!"+h+"!");
          break;
        case FT_SIZE_REQUEST_TYPE_REAL_DIM:
          h = face.ascender - face.descender;
          w = h;
Debug(0, DBG_INIT, TAG, "met2: "+w+"!"+h+"!");
          break;
        case FT_SIZE_REQUEST_TYPE_BBOX:
          w = face.bbox.xMax - face.bbox.xMin;
          h = face.bbox.yMax - face.bbox.yMin;
Debug(0, DBG_INIT, TAG, "met3: "+w+"!"+h+"!");
          break;
        case FT_SIZE_REQUEST_TYPE_CELL:
          w = face.max_advance_width;
          h = face.ascender - face.descender;
Debug(0, DBG_INIT, TAG, "met4: "+w+"!"+h+"!");
          break;
        case FT_SIZE_REQUEST_TYPE_SCALES:
          metrics.x_scale = (long)req.width;
          metrics.y_scale = (long)req.height;
          if (metrics.x_scale == 0) {
            metrics.x_scale = metrics.y_scale;
          } else {
            if (metrics.y_scale == 0) {
              metrics.y_scale = metrics.x_scale;
            }
          }
//          goto Calculate_Ppem;
          doall = false;
Debug(0, DBG_INIT, TAG, "met5: "+w+"!"+h+"!");
          break;
        case FT_SIZE_REQUEST_TYPE_MAX:
          break;
        }
        if (doall) {
          /* to be on the safe side */
          if (w < 0) {
            w = -w;
          }
          if (h < 0) {
            h = -h;
          }
          scaled_w = FTSizeRec.FT_REQUEST_WIDTH (req);
          scaled_h = FTSizeRec.FT_REQUEST_HEIGHT(req);
Debug(0, DBG_INIT, TAG, "scaled_w: "+scaled_w+"!"+scaled_h+"!"+req);
          /* determine scales */
          if (req.width != 0) {
            metrics.x_scale = FTCalc.FTDivFix(scaled_w, w);
            if (req.height != 0) {
              metrics.y_scale = FTCalc.FTDivFix(scaled_h, h);
              if (req.type == FT_SIZE_REQUEST_TYPE_CELL) {
                if (metrics.y_scale > metrics.x_scale) {
                  metrics.y_scale = metrics.x_scale;
                } else {
                  metrics.x_scale = metrics.y_scale;
                }
              }
            } else {
              metrics.y_scale = metrics.x_scale;
              scaled_h = FTCalc.FT_MulDiv(scaled_w, h, w);
            }
          } else {
            metrics.x_scale = metrics.y_scale = FTCalc.FTDivFix(scaled_h, h);
            scaled_w = FTCalc.FT_MulDiv(scaled_h, w, h);
          }
        }
        /* calculate the ppems */
        if (req.type != FTSizeRequestRec.FT_SIZE_REQUEST_TYPE_NOMINAL) {
          scaled_w = FTCalc.FTMulFix((long)face.units_per_EM, metrics.x_scale);
          scaled_h = FTCalc.FTMulFix((long)face.units_per_EM, metrics.y_scale);
        }
        metrics.x_ppem = (short)((scaled_w + 32) >> 6);
        metrics.y_ppem = (short)((scaled_h + 32) >> 6);
Debug(0, DBG_INIT, TAG, String.format("scaled: %d %d %d %d", scaled_w, scaled_h, metrics.x_ppem, metrics.y_ppem));
        FTReference<FTSizeMetricsRec> metrics_ref = new FTReference<FTSizeMetricsRec>();
        metrics_ref.Set(metrics);
        ft_recompute_scaled_metrics(face, metrics_ref);
        metrics = metrics_ref.Get();
      } else {
//        FT_ZERO( metrics );
        metrics.x_scale = 1L << 16;
        metrics.y_scale = 1L << 16;
      }
int traceLevel = 7;
      FTTrace.Trace(traceLevel, TAG, "FT_Request_Metrics:");
      FTTrace.Trace(traceLevel, TAG, String.format("  x scale: %d (%f)",
                  metrics.x_scale, metrics.x_scale / 65536.0 ));
      FTTrace.Trace(traceLevel, TAG, String.format("  y scale: %d (%f)",
                  metrics.y_scale, metrics.y_scale / 65536.0 ));
      FTTrace.Trace(traceLevel, TAG, String.format("  ascender: %f", metrics.ascender / 64.0));
      FTTrace.Trace(traceLevel, TAG, String.format("  descender: %f", metrics.descender / 64.0));
      FTTrace.Trace(traceLevel, TAG, String.format("  height: %f", metrics.height / 64.0));
      FTTrace.Trace(traceLevel, TAG, String.format("  max advance: %f", metrics.max_advance / 64.0));
      FTTrace.Trace(traceLevel, TAG, String.format("  x ppem: %d", metrics.x_ppem ));
      FTTrace.Trace(traceLevel, TAG, String.format("  y ppem: %d", metrics.y_ppem ));
      return error;
    }
 
    /* =====================================================================
     * ft_recompute_scaled_metrics
     * =====================================================================
     */
    public static int ft_recompute_scaled_metrics(FTFaceRec face, FTReference<FTSizeMetricsRec> metrics_ref) {
      int error = 0;
      FTSizeMetricsRec metrics = metrics_ref.Get();

Debug(0, DBG_INIT, TAG, "ft_recompute_scaled_metrics:");
    /* Compute root ascender, descender, test height, and max_advance */

//    metrics->ascender    = FT_PIX_CEIL( FT_MulFix( face->ascender, metrics->y_scale ) ); 
//    metrics->descender   = FT_PIX_FLOOR( FT_MulFix( face->descender, metrics->y_scale ) );
//    metrics->height      = FT_PIX_ROUND( FT_MulFix( face->height, metrics->y_scale ) );

//    metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width, metrics->x_scale ) );
      metrics.ascender = FTCalc.FTMulFix((long)face.ascender, metrics.y_scale);
      metrics.descender = FTCalc.FTMulFix((long)face.descender, metrics.y_scale);
      metrics.height = FTCalc.FTMulFix((long)face.height, metrics.y_scale);
      metrics.max_advance = FTCalc.FTMulFix((long)face.max_advance_width, metrics.x_scale);
      metrics_ref.Set(metrics);
      return error;
    }

}

Added ftbase/FTSizeRec.java.















































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTSizeRec                                                          */
  /*                                                                       */
  /* <Description>                                                         */
  /*    FreeType root size class structure.  A size object models a face   */
  /*    object at a given size.                                            */
  /*                                                                       */
  /* <Fields>                                                              */
  /*    face    :: Handle to the parent face object.                       */
  /*                                                                       */
  /*    generic :: A typeless pointer, which is unused by the FreeType     */
  /*               library or any of its drivers.  It can be used by       */
  /*               client applications to link their own data to each size */
  /*               object.                                                 */
  /*                                                                       */
  /*    metrics :: Metrics for this size object.  This field is read-only. */
  /*                                                                       */
  /* ===================================================================== */

public class FTSizeRec extends FTDebug {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTSizeRec";

    public FTFaceRec face = null;           /* parent face object              */
//    public FT_Generic generic = null;       /* generic pointer for client uses */
    public FTSizeMetricsRec metrics = null; /* size metrics                    */
//    public FTSizeInternal internal = null;  /* empty */


    /* ==================== FTSizeRec ================================== */
    public FTSizeRec() {
      oid++;
      id = oid;
//      internal = new FTSizeInternal();
      metrics = new FTSizeMetricsRec();
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
        return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
        return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* =====================================================================
     * FTNewSize
     * =====================================================================
     */
    public static int FTNewSize(FTFaceRec face, FTReference<FTSizeRec> size_ref) {
      int error = 0;
      FTDriverRec driver = null;
      FTDriverClassRec clazz;
      FTSizeRec size = null;
      FTListNodeRec node = null;

Debug(0, DBG_INIT, TAG, "FTNewSize");
      if (size_ref == null) {
        return FTError.INTERP_INVALID_SIZE_HANDLE;
      }
      if (face == null) {
        size_ref.Set(null);
        return FTError.INTERP_INVALID_FACE_HANDLE;
      }
      if (face.driver == null) {
        size_ref.Set(null);
        return FTError.INTERP_INVALID_DRIVER_HANDLE;
      }
      driver = face.driver;
      clazz  = driver.driver_clazz;
      /* Allocate new size object and perform basic initialisation */
      switch (clazz.size_object_type) {
      case TTDriverClass.SIZE_REC_TYPE_TT:
        size = (FTSizeRec)new TTSizeRec();
        break;
      default:
        return FTError.FACE_BAD_SIZE_OBJECT_TYPE;
      }
      node = new FTListNodeRec();
      if ((size == null) || (node == null)) {
        return error;
      }
      size.face = face;
      /* for now, do not use any internal fields in size objects */
//      size.internal = null;
      if (clazz.init_size != null) {
        size_ref.Set(size);
        error = (int)clazz.init_size.callClassMethod(size_ref);
        size = size_ref.Get();
      }
      /* in case of success, add to the face's list */
      if (error == 0) {
        size_ref.Set(size);
        node.data = size;
        FTListNodeRec.FTListAdd(face.sizes_list, node);
      }
      if (error != 0) {
//        FT_FREE( node );
//        FT_FREE( size );
      }
Debug(0, DBG_INIT, TAG, "FTNewSize END: "+error+"!");
      return error;
    }

    /* =====================================================================
     * FTActivateSize
     * =====================================================================
     */
    public static int FTActivateSize(FTSizeRec size) {
      int error = 0;
      FTFaceRec face;

Debug(0, DBG_INIT, TAG, "FTActivateSize");
      if (size == null) {
        return FTError.GLYPH_INVALID_ARGUMENT;
      }
      face = size.face;
      if (face == null || face.driver == null) {
        return FTError.GLYPH_INVALID_ARGUMENT;
      }
      /* we don't need anything more complex than that; all size objects */
      /* are already listed by the face                                  */
      face.size = size;
Debug(0, DBG_INIT, TAG, "FTActivateSize END: "+error+"!");
      return error;
    }

    /* =====================================================================
     * FTSetCharSize
     * =====================================================================
     */
    public static int FTSetCharSize(FTFaceRec face, int char_width, int char_height, int horz_resolution, int vert_resolution) {
      FTReference<FTSizeRequestRec> req_ref = new FTReference<FTSizeRequestRec>();
      FTSizeRequestRec req = new FTSizeRequestRec();

 Debug(0, DBG_INIT, TAG, String.format("FTSetCharSize: cw: %d ch: %d hr: %d vr: %d", char_width, char_height, horz_resolution, vert_resolution));
      if (char_width == 0) {
        char_width = char_height;
      } else {
        if (char_height == 0) {
          char_height = char_width;
        }
      }
      if (horz_resolution == 0) {
        horz_resolution = vert_resolution;
      } else {
        if (vert_resolution == 0) {
          vert_resolution = horz_resolution;
	}
      }
      if (char_width < 1 * 64) {
        char_width = 1 * 64;
      }
      if (char_height < 1 * 64) {
        char_height = 1 * 64;
      }
      if (horz_resolution == 0) {
        horz_resolution = vert_resolution = 72;
      }
      req.type = FTSizeRequestRec.FT_SIZE_REQUEST_TYPE_NOMINAL;
      req.width = char_width;
      req.height = char_height;
      req.horiResolution = horz_resolution;
      req.vertResolution = vert_resolution;
      req_ref.Set(req);
      return FTRequestSize(face, req_ref);
    }

    /* =====================================================================
     * FTRequestSize
     * =====================================================================
     */
    public static int FTRequestSize(FTFaceRec face, FTReference<FTSizeRequestRec> req_ref) {
      FTSizeRequestRec req = req_ref.Get();
      int error = 0;
      FTDriverClassRec clazz;
      long strike_index;

Debug(0, DBG_INIT, TAG, "FTRequestSize:");
      if (face == null) {
        return FTError.GLYPH_INVALID_FACE_HANDLE;
      }
      if (req == null || req.width < 0 || req.height < 0 ||
           req.type >= FTSizeRequestRec.FT_SIZE_REQUEST_TYPE_MAX) {
        return FTError.GLYPH_INVALID_ARGUMENT;
      }
      clazz = face.driver.driver_clazz;
      if (clazz.request_size != null) {
        FTSizeMetricsRec metrics = face.size.metrics;
        FTReference<Object> obj_ref = new FTReference<Object>();
Debug(0, DBG_INIT, TAG, "ME1: "+face.size.metrics.x_ppem+"!"+face.size.metrics.y_ppem+"!");
        obj_ref.Set(face.size);
        error = (int)clazz.request_size.callClassMethod(obj_ref, req);
Debug(0, DBG_INIT, TAG, "ME2: "+face.size.metrics.x_ppem+"!"+face.size.metrics.y_ppem+"!");
        face.size = (FTSizeRec)obj_ref.Get();

        FTTrace.Trace(7, TAG, "FT_Request_Size (font driver's `request_size'):");
        FTTrace.Trace(7, TAG, String.format("  x scale: %d (%f)",
                    metrics.x_scale, metrics.x_scale / 65536.0));
        FTTrace.Trace(7, TAG, String.format("  y scale: %d (%f)",
                    metrics.y_scale, metrics.y_scale / 65536.0));
        FTTrace.Trace(7, TAG, String.format("  ascender: %f", metrics.ascender / 64.0 ));
        FTTrace.Trace(7, TAG, String.format("  descender: %f", metrics.descender / 64.0 ));
        FTTrace.Trace(7, TAG,String.format( "  height: %f", metrics.height / 64.0 ));
        FTTrace.Trace(7, TAG, String.format("  max advance: %f", metrics.max_advance / 64.0));
        FTTrace.Trace(7, TAG, String.format("  x ppem: %d", metrics.x_ppem));
        FTTrace.Trace(7, TAG, String.format("  y ppem: %d", metrics.y_ppem));
        return error;
      }
      /*
       * The reason that a driver doesn't have `request_size' defined is
       * either that the scaling here suffices or that the supported formats
       * are bitmap-only and size matching is not implemented.
       *
       * In the latter case, a simple size matching is done.
       */
      if ((face.face_flags & FTFaceRec.FT_FACE_FLAG_SCALABLE) != 0 &&
	      (face.face_flags & FTFaceRec.FT_FACE_FLAG_FIXED_SIZES) != 0) {
    	  FTReference<Long> strike_index_ref = new FTReference<Long>();
//    	strike_index_Ref.Set(strike_index);
        error = FTMatchSize(face, req, false, strike_index_ref);
        strike_index = strike_index_ref.Get();
        if (error != 0) {
          return error;
        }
        return FTSelectSize(face, (int)strike_index);
      }
      FTSizeMetricsRec.FTRequestMetrics(face, req);

Debug(0, DBG_INIT, TAG, "FTRequestSize: done");
      return FTError.INTERP_ERR_OK;
    }

    /* =====================================================================
     * FT_REQUEST_WIDTH
     * =====================================================================
     */
    public static int FT_REQUEST_WIDTH(FTSizeRequestRec req) {
      return req.horiResolution != 0
              ? (int)((req.width * req.horiResolution + 36) / 72)
              : (int)req.width;
    }


    /* =====================================================================
     * FT_REQUEST_HEIGHT
     * =====================================================================
     */
    public static int FT_REQUEST_HEIGHT(FTSizeRequestRec req) {
      return req.vertResolution != 0
              ? (int)((req.height * req.vertResolution + 36) / 72)
              : (int)req.height;
    }

    /* =====================================================================
     * FTMatchSize
     * =====================================================================
     */
    public static int FTMatchSize(FTFaceRec face, FTSizeRequestRec req, boolean ignore_width, FTReference<Long> size_index_ref) {
Debug(0, DBG_INIT, TAG, "FTMatchSize:");
      int i;
      long w;
      long h;

      if ((face.face_flags & FTFaceRec.FT_FACE_FLAG_FIXED_SIZES) == 0) {
        return FTError.GLYPH_INVALID_FACE_HANDLE;
      }
      /* FT_Bitmap_Size doesn't provide enough info... */
      if (req.type != FTSizeRequestRec.FT_SIZE_REQUEST_TYPE_NOMINAL) {
        return FTError.GLYPH_UNIMPLEMENTED_FEATURE;
      }
      w = FT_REQUEST_WIDTH (req);
      h = FT_REQUEST_HEIGHT(req);
      if (req.width != 0 && req.height == 0) {
        h = w;
      } else {
        if (req.width == 0 && req.height != 0) {
          w = h;
	}
      }
      w = FTCalc.FT_PIX_ROUND(w);
      h = FTCalc.FT_PIX_ROUND(h);
      for (i = 0; i < face.num_fixed_sizes; i++) {
        FTBitmapSize bsize = face.available_sizes[i];

        if (h != FTCalc.FT_PIX_ROUND(bsize.y_ppem)) {
          continue;
        }
        if (w == FTCalc.FT_PIX_ROUND( bsize.x_ppem) || ignore_width) {
          FTTrace.Trace(7, TAG, String.format("FTMatchSize: bitmap strike %d matches", i));
          if (size_index_ref != null) {
            size_index_ref.Set(new Long(i));
          }
          return FTError.INTERP_ERR_OK;
        }
      }
      return FTError.GLYPH_INVALID_PIXEL_SIZE;
    }

    /* =====================================================================
     * FTSelectSize
     * =====================================================================
     */
    public static int FTSelectSize(FTFaceRec face, int strike_index) {
      int error = 0;

Debug(0, DBG_INIT, TAG, "FTSelectSize:");
      FTDriverClassRec clazz;

      if (face == null || (face.face_flags & FTFaceRec.FT_FACE_FLAG_FIXED_SIZES) == 0) {
        return FTError.GLYPH_INVALID_FACE_HANDLE;
      }
      if (strike_index < 0 || strike_index >= face.num_fixed_sizes) {
        return FTError.GLYPH_INVALID_ARGUMENT;
      }
      clazz = face.driver.driver_clazz;
      if (clazz.select_size != null) {
        error = (int)clazz.select_size.callClassMethod(face.size, (int)strike_index);
        FTSizeMetricsRec metrics = face.size.metrics;

        FTTrace.Trace(7, TAG, "FT_Select_Size (font driver's `select_size'):" );
        FTTrace.Trace(7, TAG, String.format("  x scale: %d (%f)",
                    metrics.x_scale, metrics.x_scale / 65536.0));
        FTTrace.Trace(7, TAG, String.format("  y scale: %d (%f)",
                    metrics.y_scale, metrics.y_scale / 65536.0));
        FTTrace.Trace(7, TAG, String.format("  ascender: %f", metrics.ascender / 64.0));
        FTTrace.Trace(7, TAG, String.format("  descender: %f", metrics.descender / 64.0));
        FTTrace.Trace(7, TAG, String.format("  height: %f", metrics.height / 64.0));
        FTTrace.Trace(7, TAG, String.format("  max advance: %f", metrics.max_advance / 64.0));
        FTTrace.Trace(7, TAG, String.format("  x ppem: %d", metrics.x_ppem));
        FTTrace.Trace(7, TAG, String.format("  y ppem: %d", metrics.y_ppem));
        return error;
      }
      FTSelectMetrics(face, (int)strike_index);
      return FTError.INTERP_ERR_OK;
    }

    /* =====================================================================
     * FTSelectMetrics
     * =====================================================================
     */
    public static int FTSelectMetrics(FTFaceRec face, int strike_index) {
      int error = 0;

Debug(0, DBG_INIT, TAG, "FTSelectMetrics:");
      FTSizeMetricsRec metrics;
      FTBitmapSize  bsize;

      metrics = face.size.metrics;
      bsize = face.available_sizes[strike_index];
      metrics.x_ppem = (short)((bsize.x_ppem + 32) >> 6);
      metrics.y_ppem = (short)((bsize.y_ppem + 32) >> 6);
      if ((face.face_flags & FTFaceRec.FT_FACE_FLAG_SCALABLE) != 0) {
        metrics.x_scale = FTCalc.FTDivFix(bsize.x_ppem, (long)face.units_per_EM );
        metrics.y_scale = FTCalc.FTDivFix(bsize.y_ppem, (long)face.units_per_EM );
        FTReference<FTSizeMetricsRec> metrics_ref = new FTReference<FTSizeMetricsRec>();
        metrics_ref.Set(metrics);
        FTSizeMetricsRec.ft_recompute_scaled_metrics(face, metrics_ref);
        metrics = metrics_ref.Get();
      } else {
        metrics.x_scale = 1L << 16;
        metrics.y_scale = 1L << 16;
        metrics.ascender = bsize.y_ppem;
        metrics.descender = 0;
        metrics.height = bsize.height << 6;
        metrics.max_advance = bsize.x_ppem;
      }
      FTTrace.Trace(7, TAG, "FT_Select_Metrics:");
      FTTrace.Trace(7, TAG, String.format("  x scale: %d (%f)",
                  metrics.x_scale, metrics.x_scale / 65536.0 ));
      FTTrace.Trace(7, TAG, String.format("  y scale: %d (%f)",
                  metrics.y_scale, metrics.y_scale / 65536.0 ));
      FTTrace.Trace(7, TAG, String.format("  ascender: %f",metrics.ascender / 64.0 ));
      FTTrace.Trace(7, TAG, String.format("  descender: %f", metrics.descender / 64.0 ));
      FTTrace.Trace(7, TAG, String.format("  height: %f", metrics.height / 64.0 ));
      FTTrace.Trace(7, TAG, String.format("  max advance: %f", metrics.max_advance / 64.0 ));
      FTTrace.Trace(7, TAG, String.format("  x ppem: %d", metrics.x_ppem ));
      FTTrace.Trace(7, TAG, String.format("  y ppem: %d", metrics.y_ppem ));
      return error;
    }

}

Added ftbase/FTSizeRequestRec.java.



























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTSizeRequestRec                                                   */
  /*                                                                       */
  /* <Description>                                                         */
  /*    A structure used to model a size request.                          */
  /*                                                                       */
  /* <Fields>                                                              */
  /*    type           :: See @FT_Size_Request_Type.                       */
  /*                                                                       */
  /*    width          :: The desired width.                               */
  /*                                                                       */
  /*    height         :: The desired height.                              */
  /*                                                                       */
  /*    horiResolution :: The horizontal resolution.  If set to zero,      */
  /*                      `width' is treated as a 26.6 fractional pixel    */
  /*                      value.                                           */
  /*                                                                       */
  /*    vertResolution :: The vertical resolution.  If set to zero,        */
  /*                      `height' is treated as a 26.6 fractional pixel   */
  /*                      value.                                           */
  /*                                                                       */
  /* <Note>                                                                */
  /*    If `width' is zero, then the horizontal scaling value is set equal */
  /*    to the vertical scaling value, and vice versa.                     */
  /*                                                                       */
  /* ===================================================================== */

public class FTSizeRequestRec extends FTDebug {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTSizeRequestRec";

    public int type = 0;
    public long width = 0L;
    public long height = 0L;
    public int horiResolution = 0;
    public int vertResolution = 0;

    /* ==================== FTSizeRequestRec ================================== */
    public FTSizeRequestRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
}

Added ftbase/FTSlotInternalRec.java.











































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
// ----------------------------------------------------------------
// FTSlotInternalRec.java --
//
// Copyright (c) 2014 by Arnulf P. Wiedemann
//
// See the file "license.terms" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//------------------------------------------------------------------------

package ftbase;

//import android.util.Log;

/* ======================================================================= */
/*  This Java implementation is derived from the Freetype code             */
/*  and has been implemented to work together with the Apache batik code   */
/*  for reading .ttf font files                                             */
/*                                                                         */
/*  Copyright (C) of the Java implementation 2014                          */
/*  Arnulf Wiedemann                                                       */
/*                                                                         */
/*  See the file "license.terms" for information on usage and              */
/*  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.   */
/*                                                                         */
/*  in this directory the truetype opcode interpreter is ported to Java    */
/*                                                                         */
/*  the next blocks are taken from the original source code                */
/*                                                                         */
/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
/*            2010 by                                                      */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/* ======================================================================= */

  /* ===================================================================== */
  /*    FTSlotInternalRec                                                          */
  /*                                                                       */
  /* <Description>                                                         */
  /*    This structure contains the internal fields of each FT_GlyphSlot   */
  /*    object.  These fields may change between different releases of     */
  /*    FreeType.                                                          */
  /*                                                                       */
  /* <Fields>                                                              */
  /*    loader            :: The glyph loader object used to load outlines */
  /*                         into the glyph slot.                          */
  /*                                                                       */
  /*    flags             :: Possible values are zero or                   */
  /*                         FT_GLYPH_OWN_BITMAP.  The latter indicates    */
  /*                         that the FT_GlyphSlot structure owns the      */
  /*                         bitmap buffer.                                */
  /*                                                                       */
  /*    glyph_transformed :: Boolean.  Set to TRUE when the loaded glyph   */
  /*                         must be transformed through a specific        */
  /*                         font transformation.  This is _not_ the same  */
  /*                         as the face transform set through             */
  /*                         FT_Set_Transform().                           */
  /*                                                                       */
  /*    glyph_matrix      :: The 2x2 matrix corresponding to the glyph     */
  /*                         transformation, if necessary.                 */
  /*                                                                       */
  /*    glyph_delta       :: The 2d translation vector corresponding to    */
  /*                         the glyph transformation, if necessary.       */
  /*                                                                       */
  /*    glyph_hints       :: Format-specific glyph hints management.       */
  /*                                                                       */
  /* ===================================================================== */

public class FTSlotInternalRec extends Object {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTSlotInternalRec";

    public final static int FT_GLYPH_OWN_BITMAP  = 0x1;

    public FTGlyphLoaderRec loader = null;
    public Integer flags = 0;
    public boolean glyph_transformed = false;
    public FTMatrixRec glyph_matrix = null;
    public FTVectorRec glyph_delta = null;
    public Object[] glyph_hints = null;

    /* ==================== FTSlotInternalRec ================================== */
    public FTSlotInternalRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      String str = TAG+"!"+id+"!";
      return str;
    } 
        
    /* ==================== toString ===================================== */
    public String toString() {
      StringBuffer str = new StringBuffer(mySelf()+"!");
      return str.toString();
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* =====================================================================
     * =====================================================================
     */

}

Added ftbase/FTStreamRec.java.











































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

import java.io.*;
  /* =====================================================================
   *    FTStreamRec
   *
   * @description:
   *   A structure used to describe an input stream.
   *
   * @input:
   *   base ::
   *     For memory-based streams, this is the address of the first stream
   *     byte in memory.  This field should always be set to NULL for
   *     disk-based streams.
   *
   *   size ::
   *     The stream size in bytes.
   *
   *   pos ::
   *     The current position within the stream.
   *
   *   descriptor ::
   *     This field is a union that can hold an integer or a pointer.  It is
   *     used by stream implementations to store file descriptors or `FILE*'
   *     pointers.
   *
   *   pathname ::
   *     This field is completely ignored by FreeType.  However, it is often
   *     useful during debugging to use it to store the stream's filename
   *     (where available).
   *
   *   read ::
   *     The stream's input function.
   *
   *   close ::
   *     The stream's close function.
   *
   *   memory ::
   *     The memory manager to use to preload frames.  This is set
   *     internally by FreeType and shouldn't be touched by stream
   *     implementations.
   *
   *   cursor ::
   *     This field is set and used internally by FreeType when parsing
   *     frames.
   *
   *   limit ::
   *     This field is set and used internally by FreeType when parsing
   *     frames.
   * =====================================================================
   */

public class FTStreamRec extends FTDebug {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTStreamRec";
    
    public RandomAccessFile raf = null;

    public Byte[] base = null;
    public long size = 0L;
    public long pos = 0L;
    public Object descriptor;
    public Object pathname;
//    public FTStreamIoFunc read;
//    public FTStreamCloseFunc close;
    public long cursor = 0L;
    public long limit = 0L;

    /* ==================== FTStreamRec ================================== */
    public FTStreamRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* =====================================================================
     * create a new input stream from an FTOpenArgs structure
     * =====================================================================
     */
    public int FTStreamNew(FTLibraryRec library, FTOpenArgs args, FTReference<RandomAccessFile> stream_ref) {
      int error = 0;
//      FT_Memory  memory;

      if (library == null) {
        stream_ref.Set(null);
        return FTError.INTERP_INVALID_LIBRARY_HANDLE;
      }
      if (args == null) {
Debug(0, DBG_INIT, TAG, "FTStreamRecNew1 inv arg");
        stream_ref.Set(null);
        return FTError.INTERP_INVALID_ARGUMENT;
      }
      FTTrace.Trace(7, TAG, "read font file");
      if ((args.flags & FTOpenArgs.FT_OPEN_MEMORY) != 0) {
        /* create a memory-based stream */
//        FT_StreamRec_OpenMemory(stream, args.memory_base, args.memory_size);
      } else {
        if ((args.flags & FTOpenArgs.FT_OPEN_PATHNAME) != 0) {
          /* create a normal system stream */
          error = 0;
          try {
Debug(0, DBG_INIT, TAG, "pathname: "+args.pathname+"!");
            raf = new RandomAccessFile(args.pathname, "r");
            size = raf.length();
	    limit = size;
          } catch (FileNotFoundException e) {
            e.printStackTrace();
            return FTError.INTERP_INVALID_STREAM_OPERATION;
          } catch (IOException e) {
              e.printStackTrace();
              return FTError.INTERP_INVALID_STREAM_OPERATION;
          }
//          error = FTStreamRecOpen(stream, args.pathname);
          pathname = args.pathname;
        } else {
          if ((args.flags & FTOpenArgs.FT_OPEN_STREAM) != 0 && args.stream != null) {
            /* use an existing, user-provided stream */
            /* in this case, we do not need to allocate a new stream object */
            /* since the caller is responsible for closing it himself       */
//            FT_FREE(stream);
//            stream = args.stream;
          } else {
Debug(0, DBG_INIT, TAG, "FTStreamRecNew2 inv arg");
            error = FTError.INTERP_INVALID_ARGUMENT;
          }
        }
      }
      if (error != 0) {
//        FT_FREE(stream);
        stream_ref.Set(null);
        return error;
      } else {
//        stream->memory = memory;  /* just to be certain */
      }
      stream_ref.Set(raf);
      return error;
    }

    /* =====================================================================
     * FTStreamFree
     * =====================================================================
     */
    public void FTStreamFree(RandomAccessFile stream, int external) {
      try {
        raf.close();
      } catch (IOException e) {
    	e.printStackTrace();  
      }
      if (stream != null) {
//        FTStreamRecClose(stream);
        if (external  == 0) {
//          FT_FREE(stream);
        }
      }
    }

    /* =====================================================================
     * pos
     * =====================================================================
     */
    public long pos() {
      try {
        return raf.getFilePointer();
      } catch (IOException e) {
    	  e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * seek
     * =====================================================================
     */
    public long seek(long offset) {
      try {
        raf.seek(offset);
        cursor = offset;
        return pos();
      } catch (IOException e) {
        e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * read
     * =====================================================================
     */
    public int read(byte[] buffer, short lgth, FTStreamRec stream) {
      try {
        cursor += lgth;
        return stream.raf.read(buffer, 0, lgth);
      } catch (IOException e) {
        e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readByteArray
     * =====================================================================
     */
    public int readByteArray(byte[] buffer, short lgth, FTStreamRec stream) {
      try {
    	for (int i = 0; i < lgth; i++) {
          buffer[i] = stream.raf.readByte();
    	}
        cursor += lgth;
    	return lgth;
      } catch (IOException e) {
        e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readLong
     * =====================================================================
     */
    public long readLong(FTStreamRec stream) {
      try {
        cursor += 4;
        return stream.raf.readLong();
      } catch (IOException e) {
      	e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readLong
     * =====================================================================
     */
    public Object readLong(Object ... args) {
      try {
        FTStreamRec stream = (FTStreamRec)args[0];
        cursor += 4;
        return (Object)new Long(stream.raf.readLong());
      } catch (IOException e) {
        e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readInt
     * =====================================================================
     */
    public int readInt(FTStreamRec stream) {
      try {
        cursor += 4;
        return new Integer(stream.raf.readInt()).intValue();
      } catch (IOException e) {
        e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readInt
     * =====================================================================
     */
    public Object readInt(Object ... args) {
      try {
        FTStreamRec stream = (FTStreamRec)args[0];
        cursor += 4;
        return (Object)new Integer(stream.raf.readInt());
      } catch (IOException e) {
        e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readShort
     * =====================================================================
     */
    public short readShort(FTStreamRec stream) {
      try {
        cursor += 2;
        return new Short(stream.raf.readShort()).shortValue();
      } catch (IOException e) {
  	     e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readShort
     * =====================================================================
     */
    public Object readShort(Object ... args) {
      try {
        FTStreamRec stream = (FTStreamRec)args[0];
        cursor += 2;
        return (Object)new Short(stream.raf.readShort());
      } catch (IOException e) {
        e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readByte
     * =====================================================================
     */
    public byte readByte(FTStreamRec stream) {
      try {
        cursor += 1;
        return stream.raf.readByte();
      } catch (IOException e) {
       e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * readByte
     * =====================================================================
     */
    public Object readByte(Object ... args) {
      try {
        FTStreamRec stream = (FTStreamRec)args[0];
        cursor += 1;
        return (Object)stream.raf.readByte();
      } catch (IOException e) {
        e.printStackTrace();
      }
      return -1;
    }

    /* =====================================================================
     * FTStreamEnterFrame
     * =====================================================================
     */
    public int FTStreamEnterFrame(long count) {
      if (count > size) {
        return FTError.STREAM_READ_AFTER_SIZE;
      }
      return 0;
    }
     
}

Added ftbase/FTStrokeBorderRec.java.



















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTStrokeBorderRec                                                          */
  /*                                                                       */
  /* ===================================================================== */

public class FTStrokeBorderRec extends FTDebug {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTStrokeBorderRec";

    public int num_points = 0;
    public int max_points = 0;
    public FTVectorRec[] points = null;
    public byte[] tags = null;
    public boolean movable = false; /* TRUE for ends of lineto borders */
    public int start = -1;          /* index of current sub-path start point */
    public boolean valid = false;

    /* ==================== FTStrokeBorderRec ================================== */
    public FTStrokeBorderRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
}

Added ftbase/FTStrokerRec.java.



































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTStrokerRec                                                          */
  /*                                                                       */
  /* ===================================================================== */

public class FTStrokerRec extends FTDebug {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTStrokerRec";

    public final static int FT_STROKER_LINECAP_BUTT = 0;
    public final static int FT_STROKER_LINECAP_ROUND = 1;
    public final static int FT_STROKER_LINECAP_SQUARE = 2;
    public final static int FT_STROKER_LINEJOIN_ROUND = 0;
    public final static int FT_STROKER_LINEJOIN_BEVEL = 1;
    public final static int FT_STROKER_LINEJOIN_MITER_VARIABLE = 2;
    public final static int FT_STROKER_LINEJOIN_MITER = 2;
    public final static int FT_STROKER_LINEJOIN_MITER_FIXED = 3;

    public long angle_in = 0L;             /* direction into curr join */
    public long angle_out = 0L;            /* direction out of join  */
    public FTVectorRec center = null;               /* current position */
    public long line_length = 0L;          /* length of last lineto */
    public boolean first_point = false;          /* is this the start? */
    public boolean subpath_open = false;         /* is the subpath open? */
    public long subpath_angle = 0L;        /* subpath start direction */
    public FTVectorRec subpath_start = null;        /* subpath start position */
    public long subpath_line_length = 0L;  /* subpath start lineto len */
    public boolean handle_wide_strokes = false;  /* use wide strokes logic? */
    public int line_cap = 0;
    public int line_join = 0;
    public int line_join_saved = 0;
    public long miter_limit = 0L;
    public long radius = 0L;
    public FTStrokeBorderRec[] borders = new FTStrokeBorderRec[2];
    public FTLibraryRec library = null;

    /* ==================== FTStrokerRec ================================== */
    public FTStrokerRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
    /* =====================================================================
     * FTStrokerNew
     * =====================================================================
     */
    public static int FTStrokerNew(FTLibraryRec library, FTReference<FTStrokerRec> stroker_ref) {
      int error = 0;
      FTStrokerRec stroker = null;

      if (library == null) {
        return FTError.GLYPH_INVALID_ARGUMENT;
      }
      stroker = new FTStrokerRec();
      if (stroker != null) {
        stroker.library = library;
        stroker.borders[0] = new FTStrokeBorderRec();
        stroker.borders[1] = new FTStrokeBorderRec();
      }
      stroker_ref.Set(stroker);
      return error;
    }

}

Added ftbase/FTSubGlyphRec.java.































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* =====================================================================
 *  This Java implementation is derived from FreeType code
 *  Portions of this software are copyright (C) 2014 The FreeType
 *  Project (www.freetype.org).  All rights reserved.
 *
 *  Copyright (C) of the Java implementation 2014
 *  Arnulf Wiedemann arnulf at wiedemann-pri.de
 *
 *  See the file "license.terms" for information on usage and
 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * =====================================================================
 */

package ftbase;

  /* ===================================================================== */
  /*    FTSubGlyphRec                                                          */
  /*                                                                       */
  /* ===================================================================== */

public class FTSubGlyphRec extends Object {
    private static int oid = 0;

    private int id;
    private static String TAG = "FTSubGlyphRec";

    public final static int FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS     =     1;
    public final static int FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES =     2;
    public final static int FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID   =     4;
    public final static int FT_SUBGLYPH_FLAG_SCALE              =     8;
    public final static int FT_SUBGLYPH_FLAG_XY_SCALE           =  0x40;
    public final static int FT_SUBGLYPH_FLAG_2X2                =  0x80;
    public final static int FT_SUBGLYPH_FLAG_USE_MY_METRICS     = 0x200;

    public int index = 0;
    public short flags = 0;
    public int arg1 = 0;
    public int arg2 = 0;
    public FTMatrixRec transform = null;

    /* ==================== FTSubGlyphRec ================================== */
    public FTSubGlyphRec() {
      oid++;
      id = oid;
    }
    
    /* ==================== mySelf ================================== */
    public String mySelf() {
      return TAG+"!"+id+"!";
    }
        
    /* ==================== toString ===================================== */
    public String toString() {
      return mySelf()+"!";
    }

    /* ==================== toDebugString ===================================== */
    public String toDebugString() {
      StringBuffer str = new StringBuffer(mySelf()+"\n");
      return str.toString();
    }
 
}