Alexei Podtelezhnikov pushed to branch master at FreeType / FreeType
Commits:
-
de94e2cb
by Alexei Podtelezhnikov at 2023-03-06T16:23:14-05:00
[truetype] Simplify memory management.
Instead of using `Update_Max`, switch to regular FreeType memory
allocation macros, stop pre-allocating the glyph instruction arrays.
* src/truetype/ttgload.c (TT_Load_Simple_Glyph,
TT_Process_Composite_Glyph): Switch to regular memory allocation.
* src/truetype/ttinterp.c (Update_Max): Removed.
(TT_Load_Context): Reallocate stack and free old instructions.
(Modify_CVT_Check, Ins_WS): Switch to regular memory allocation.
* src/truetype/ttinterp.h (Update_Max): Removed.
3 changed files:
Changes:
src/truetype/ttgload.c
... |
... |
@@ -437,7 +437,8 @@ |
437
|
437
|
|
438
|
438
|
if ( IS_HINTED( load->load_flags ) )
|
439
|
439
|
{
|
440
|
|
- FT_ULong tmp;
|
|
440
|
+ TT_ExecContext exec = load->exec;
|
|
441
|
+ FT_Memory memory = exec->memory;
|
441
|
442
|
|
442
|
443
|
|
443
|
444
|
/* check instructions size */
|
... |
... |
@@ -449,24 +450,19 @@ |
449
|
450
|
}
|
450
|
451
|
|
451
|
452
|
/* we don't trust `maxSizeOfInstructions' in the `maxp' table */
|
452
|
|
- /* and thus update the bytecode array size by ourselves */
|
|
453
|
+ /* and thus allocate the bytecode array size by ourselves */
|
|
454
|
+ if ( n_ins )
|
|
455
|
+ {
|
|
456
|
+ if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) )
|
|
457
|
+ return error;
|
453
|
458
|
|
454
|
|
- tmp = load->exec->glyphSize;
|
455
|
|
- error = Update_Max( load->exec->memory,
|
456
|
|
- &tmp,
|
457
|
|
- sizeof ( FT_Byte ),
|
458
|
|
- (void*)&load->exec->glyphIns,
|
459
|
|
- n_ins );
|
|
459
|
+ FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins );
|
460
|
460
|
|
461
|
|
- load->exec->glyphSize = (FT_UInt)tmp;
|
462
|
|
- if ( error )
|
463
|
|
- return error;
|
464
|
|
-
|
465
|
|
- load->glyph->control_len = n_ins;
|
466
|
|
- load->glyph->control_data = load->exec->glyphIns;
|
|
461
|
+ exec->glyphSize = n_ins;
|
467
|
462
|
|
468
|
|
- if ( n_ins )
|
469
|
|
- FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
|
|
463
|
+ load->glyph->control_len = n_ins;
|
|
464
|
+ load->glyph->control_data = exec->glyphIns;
|
|
465
|
+ }
|
470
|
466
|
}
|
471
|
467
|
|
472
|
468
|
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
... |
... |
@@ -1331,12 +1327,12 @@ |
1331
|
1327
|
FT_UInt start_contour )
|
1332
|
1328
|
{
|
1333
|
1329
|
FT_Error error;
|
1334
|
|
- FT_Outline* outline;
|
|
1330
|
+ FT_Outline* outline = &loader->gloader->base.outline;
|
|
1331
|
+ FT_Stream stream = loader->stream;
|
|
1332
|
+ FT_UShort n_ins;
|
1335
|
1333
|
FT_UInt i;
|
1336
|
1334
|
|
1337
|
1335
|
|
1338
|
|
- outline = &loader->gloader->base.outline;
|
1339
|
|
-
|
1340
|
1336
|
/* make room for phantom points */
|
1341
|
1337
|
error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
|
1342
|
1338
|
outline->n_points + 4,
|
... |
... |
@@ -1351,53 +1347,40 @@ |
1351
|
1347
|
|
1352
|
1348
|
#ifdef TT_USE_BYTECODE_INTERPRETER
|
1353
|
1349
|
|
1354
|
|
- {
|
1355
|
|
- FT_Stream stream = loader->stream;
|
1356
|
|
- FT_UShort n_ins, max_ins;
|
1357
|
|
- FT_ULong tmp;
|
|
1350
|
+ /* TT_Load_Composite_Glyph only gives us the offset of instructions */
|
|
1351
|
+ /* so we read them here */
|
|
1352
|
+ if ( FT_STREAM_SEEK( loader->ins_pos ) ||
|
|
1353
|
+ FT_READ_USHORT( n_ins ) )
|
|
1354
|
+ return error;
|
1358
|
1355
|
|
|
1356
|
+ FT_TRACE5(( " Instructions size = %hu\n", n_ins ));
|
1359
|
1357
|
|
1360
|
|
- /* TT_Load_Composite_Glyph only gives us the offset of instructions */
|
1361
|
|
- /* so we read them here */
|
1362
|
|
- if ( FT_STREAM_SEEK( loader->ins_pos ) ||
|
1363
|
|
- FT_READ_USHORT( n_ins ) )
|
1364
|
|
- return error;
|
|
1358
|
+ if ( !n_ins )
|
|
1359
|
+ return FT_Err_Ok;
|
1365
|
1360
|
|
1366
|
|
- FT_TRACE5(( " Instructions size = %hu\n", n_ins ));
|
1367
|
|
-
|
1368
|
|
- /* check it */
|
1369
|
|
- max_ins = loader->face->max_profile.maxSizeOfInstructions;
|
1370
|
|
- if ( n_ins > max_ins )
|
1371
|
|
- {
|
1372
|
|
- /* don't trust `maxSizeOfInstructions'; */
|
1373
|
|
- /* only do a rough safety check */
|
1374
|
|
- if ( n_ins > loader->byte_len )
|
1375
|
|
- {
|
1376
|
|
- FT_TRACE1(( "TT_Process_Composite_Glyph:"
|
1377
|
|
- " too many instructions (%hu) for glyph with length %u\n",
|
1378
|
|
- n_ins, loader->byte_len ));
|
1379
|
|
- return FT_THROW( Too_Many_Hints );
|
1380
|
|
- }
|
|
1361
|
+ /* don't trust `maxSizeOfInstructions'; */
|
|
1362
|
+ /* only do a rough safety check */
|
|
1363
|
+ if ( n_ins > loader->byte_len )
|
|
1364
|
+ {
|
|
1365
|
+ FT_TRACE1(( "TT_Process_Composite_Glyph:"
|
|
1366
|
+ " too many instructions (%hu) for glyph with length %u\n",
|
|
1367
|
+ n_ins, loader->byte_len ));
|
|
1368
|
+ return FT_THROW( Too_Many_Hints );
|
|
1369
|
+ }
|
1381
|
1370
|
|
1382
|
|
- tmp = loader->exec->glyphSize;
|
1383
|
|
- error = Update_Max( loader->exec->memory,
|
1384
|
|
- &tmp,
|
1385
|
|
- sizeof ( FT_Byte ),
|
1386
|
|
- (void*)&loader->exec->glyphIns,
|
1387
|
|
- n_ins );
|
|
1371
|
+ {
|
|
1372
|
+ TT_ExecContext exec = loader->exec;
|
|
1373
|
+ FT_Memory memory = exec->memory;
|
1388
|
1374
|
|
1389
|
|
- loader->exec->glyphSize = (FT_UShort)tmp;
|
1390
|
|
- if ( error )
|
1391
|
|
- return error;
|
1392
|
|
- }
|
1393
|
|
- else if ( n_ins == 0 )
|
1394
|
|
- return FT_Err_Ok;
|
1395
|
1375
|
|
1396
|
|
- if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
|
|
1376
|
+ if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ||
|
|
1377
|
+ FT_STREAM_READ( exec->glyphIns, n_ins ) )
|
1397
|
1378
|
return error;
|
1398
|
1379
|
|
1399
|
|
- loader->glyph->control_data = loader->exec->glyphIns;
|
|
1380
|
+ exec->glyphSize = n_ins;
|
|
1381
|
+
|
1400
|
1382
|
loader->glyph->control_len = n_ins;
|
|
1383
|
+ loader->glyph->control_data = exec->glyphIns;
|
1401
|
1384
|
}
|
1402
|
1385
|
|
1403
|
1386
|
#endif
|
src/truetype/ttinterp.c
... |
... |
@@ -275,57 +275,6 @@ |
275
|
275
|
}
|
276
|
276
|
|
277
|
277
|
|
278
|
|
- /**************************************************************************
|
279
|
|
- *
|
280
|
|
- * @Function:
|
281
|
|
- * Update_Max
|
282
|
|
- *
|
283
|
|
- * @Description:
|
284
|
|
- * Checks the size of a buffer and reallocates it if necessary.
|
285
|
|
- *
|
286
|
|
- * @Input:
|
287
|
|
- * memory ::
|
288
|
|
- * A handle to the parent memory object.
|
289
|
|
- *
|
290
|
|
- * multiplier ::
|
291
|
|
- * The size in bytes of each element in the buffer.
|
292
|
|
- *
|
293
|
|
- * new_max ::
|
294
|
|
- * The new capacity (size) of the buffer.
|
295
|
|
- *
|
296
|
|
- * @InOut:
|
297
|
|
- * size ::
|
298
|
|
- * The address of the buffer's current size expressed
|
299
|
|
- * in elements.
|
300
|
|
- *
|
301
|
|
- * buff ::
|
302
|
|
- * The address of the buffer base pointer.
|
303
|
|
- *
|
304
|
|
- * @Return:
|
305
|
|
- * FreeType error code. 0 means success.
|
306
|
|
- */
|
307
|
|
- FT_LOCAL_DEF( FT_Error )
|
308
|
|
- Update_Max( FT_Memory memory,
|
309
|
|
- FT_ULong* size,
|
310
|
|
- FT_ULong multiplier,
|
311
|
|
- void* _pbuff,
|
312
|
|
- FT_ULong new_max )
|
313
|
|
- {
|
314
|
|
- FT_Error error;
|
315
|
|
- void** pbuff = (void**)_pbuff;
|
316
|
|
-
|
317
|
|
-
|
318
|
|
- if ( *size < new_max )
|
319
|
|
- {
|
320
|
|
- if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
|
321
|
|
- return error;
|
322
|
|
- *size = new_max;
|
323
|
|
- }
|
324
|
|
-
|
325
|
|
- return FT_Err_Ok;
|
326
|
|
- }
|
327
|
|
-
|
328
|
|
-
|
329
|
278
|
/**************************************************************************
|
330
|
279
|
*
|
331
|
280
|
* @Function:
|
... |
... |
@@ -359,9 +308,9 @@ |
359
|
308
|
TT_Size size )
|
360
|
309
|
{
|
361
|
310
|
FT_Int i;
|
362
|
|
- FT_ULong tmp;
|
363
|
311
|
TT_MaxProfile* maxp;
|
364
|
312
|
FT_Error error;
|
|
313
|
+ FT_Memory memory = exec->memory;
|
365
|
314
|
|
366
|
315
|
|
367
|
316
|
exec->face = face;
|
... |
... |
@@ -406,25 +355,15 @@ |
406
|
355
|
|
407
|
356
|
/* XXX: We reserve a little more elements on the stack to deal safely */
|
408
|
357
|
/* with broken fonts like arialbs, courbs, timesbs, etc. */
|
409
|
|
- tmp = (FT_ULong)exec->stackSize;
|
410
|
|
- error = Update_Max( exec->memory,
|
411
|
|
- &tmp,
|
412
|
|
- sizeof ( FT_F26Dot6 ),
|
413
|
|
- (void*)&exec->stack,
|
414
|
|
- maxp->maxStackElements + 32 );
|
415
|
|
- exec->stackSize = (FT_Long)tmp;
|
416
|
|
- if ( error )
|
|
358
|
+ if ( FT_QRENEW_ARRAY( exec->stack,
|
|
359
|
+ exec->stackSize,
|
|
360
|
+ maxp->maxStackElements + 32 ) )
|
417
|
361
|
return error;
|
|
362
|
+ exec->stackSize = maxp->maxStackElements + 32;
|
418
|
363
|
|
419
|
|
- tmp = (FT_ULong)exec->glyphSize;
|
420
|
|
- error = Update_Max( exec->memory,
|
421
|
|
- &tmp,
|
422
|
|
- sizeof ( FT_Byte ),
|
423
|
|
- (void*)&exec->glyphIns,
|
424
|
|
- maxp->maxSizeOfInstructions );
|
425
|
|
- exec->glyphSize = (FT_UInt)tmp;
|
426
|
|
- if ( error )
|
427
|
|
- return error;
|
|
364
|
+ /* free previous glyph code range */
|
|
365
|
+ FT_FREE( exec->glyphIns );
|
|
366
|
+ exec->glyphSize = 0;
|
428
|
367
|
|
429
|
368
|
exec->pts.n_points = 0;
|
430
|
369
|
exec->pts.n_contours = 0;
|
... |
... |
@@ -1530,14 +1469,16 @@ |
1530
|
1469
|
if ( exc->iniRange == tt_coderange_glyph &&
|
1531
|
1470
|
exc->cvt != exc->glyfCvt )
|
1532
|
1471
|
{
|
1533
|
|
- exc->error = Update_Max( exc->memory,
|
1534
|
|
- &exc->glyfCvtSize,
|
1535
|
|
- sizeof ( FT_Long ),
|
1536
|
|
- (void*)&exc->glyfCvt,
|
1537
|
|
- exc->cvtSize );
|
1538
|
|
- if ( exc->error )
|
|
1472
|
+ FT_Memory memory = exc->memory;
|
|
1473
|
+ FT_Error error;
|
|
1474
|
+
|
|
1475
|
+
|
|
1476
|
+ FT_MEM_QRENEW_ARRAY( exc->glyfCvt, exc->glyfCvtSize, exc->cvtSize );
|
|
1477
|
+ exc->error = error;
|
|
1478
|
+ if ( error )
|
1539
|
1479
|
return;
|
1540
|
1480
|
|
|
1481
|
+ exc->glyfCvtSize = exc->cvtSize;
|
1541
|
1482
|
FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
|
1542
|
1483
|
exc->cvt = exc->glyfCvt;
|
1543
|
1484
|
}
|
... |
... |
@@ -3117,18 +3058,18 @@ |
3117
|
3058
|
if ( exc->iniRange == tt_coderange_glyph &&
|
3118
|
3059
|
exc->storage != exc->glyfStorage )
|
3119
|
3060
|
{
|
3120
|
|
- FT_ULong tmp = (FT_ULong)exc->glyfStoreSize;
|
|
3061
|
+ FT_Memory memory = exc->memory;
|
|
3062
|
+ FT_Error error;
|
3121
|
3063
|
|
3122
|
3064
|
|
3123
|
|
- exc->error = Update_Max( exc->memory,
|
3124
|
|
- &tmp,
|
3125
|
|
- sizeof ( FT_Long ),
|
3126
|
|
- (void*)&exc->glyfStorage,
|
3127
|
|
- exc->storeSize );
|
3128
|
|
- exc->glyfStoreSize = (FT_UShort)tmp;
|
3129
|
|
- if ( exc->error )
|
|
3065
|
+ FT_MEM_QRENEW_ARRAY( exc->glyfStorage,
|
|
3066
|
+ exc->glyfStoreSize,
|
|
3067
|
+ exc->storeSize );
|
|
3068
|
+ exc->error = error;
|
|
3069
|
+ if ( error )
|
3130
|
3070
|
return;
|
3131
|
3071
|
|
|
3072
|
+ exc->glyfStoreSize = exc->storeSize;
|
3132
|
3073
|
FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
|
3133
|
3074
|
exc->storage = exc->glyfStorage;
|
3134
|
3075
|
}
|
src/truetype/ttinterp.h
... |
... |
@@ -460,14 +460,6 @@ FT_BEGIN_HEADER |
460
|
460
|
FT_LOCAL( void )
|
461
|
461
|
TT_Clear_CodeRange( TT_ExecContext exec,
|
462
|
462
|
FT_Int range );
|
463
|
|
-
|
464
|
|
-
|
465
|
|
- FT_LOCAL( FT_Error )
|
466
|
|
- Update_Max( FT_Memory memory,
|
467
|
|
- FT_ULong* size,
|
468
|
|
- FT_ULong multiplier,
|
469
|
|
- void* _pbuff,
|
470
|
|
- FT_ULong new_max );
|
471
|
463
|
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
472
|
464
|
|
473
|
465
|
|
|