| OLD | NEW |
| 1 /***************************************************************************/ | 1 /***************************************************************************/ |
| 2 /* */ | 2 /* */ |
| 3 /* cf2intrp.c */ | 3 /* cf2intrp.c */ |
| 4 /* */ | 4 /* */ |
| 5 /* Adobe's CFF Interpreter (body). */ | 5 /* Adobe's CFF Interpreter (body). */ |
| 6 /* */ | 6 /* */ |
| 7 /* Copyright 2007-2013 Adobe Systems Incorporated. */ | 7 /* Copyright 2007-2013 Adobe Systems Incorporated. */ |
| 8 /* */ | 8 /* */ |
| 9 /* This software, and all works of authorship, whether in source or */ | 9 /* This software, and all works of authorship, whether in source or */ |
| 10 /* object code form as indicated by the copyright notice(s) included */ | 10 /* object code form as indicated by the copyright notice(s) included */ |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 | 457 |
| 458 /* TODO: placeholders for hint structures */ | 458 /* TODO: placeholders for hint structures */ |
| 459 | 459 |
| 460 /* objects used for hinting */ | 460 /* objects used for hinting */ |
| 461 CF2_ArrStackRec hStemHintArray; | 461 CF2_ArrStackRec hStemHintArray; |
| 462 CF2_ArrStackRec vStemHintArray; | 462 CF2_ArrStackRec vStemHintArray; |
| 463 | 463 |
| 464 CF2_HintMaskRec hintMask; | 464 CF2_HintMaskRec hintMask; |
| 465 CF2_GlyphPathRec glyphPath; | 465 CF2_GlyphPathRec glyphPath; |
| 466 | 466 |
| 467 int refCount = 0; | |
| 468 | |
| 469 | |
| 470 /* initialize the remaining objects */ | 467 /* initialize the remaining objects */ |
| 471 cf2_arrstack_init( &subrStack, | 468 cf2_arrstack_init( &subrStack, |
| 472 memory, | 469 memory, |
| 473 error, | 470 error, |
| 474 sizeof ( CF2_BufferRec ) ); | 471 sizeof ( CF2_BufferRec ) ); |
| 475 cf2_arrstack_init( &hStemHintArray, | 472 cf2_arrstack_init( &hStemHintArray, |
| 476 memory, | 473 memory, |
| 477 error, | 474 error, |
| 478 sizeof ( CF2_StemHintRec ) ); | 475 sizeof ( CF2_StemHintRec ) ); |
| 479 cf2_arrstack_init( &vStemHintArray, | 476 cf2_arrstack_init( &vStemHintArray, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack ); | 541 charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack ); |
| 545 *charstring = *buf; /* structure copy */ | 542 *charstring = *buf; /* structure copy */ |
| 546 | 543 |
| 547 charstringIndex = 0; /* entry is valid now */ | 544 charstringIndex = 0; /* entry is valid now */ |
| 548 | 545 |
| 549 /* catch errors so far */ | 546 /* catch errors so far */ |
| 550 if ( *error ) | 547 if ( *error ) |
| 551 goto exit; | 548 goto exit; |
| 552 | 549 |
| 553 /* main interpreter loop */ | 550 /* main interpreter loop */ |
| 554 while ( refCount++ < 10240 ) | 551 while ( 1 ) |
| 555 { | 552 { |
| 556 if ( cf2_buf_isEnd( charstring ) ) | 553 if ( cf2_buf_isEnd( charstring ) ) |
| 557 { | 554 { |
| 558 /* If we've reached the end of the charstring, simulate a */ | 555 /* If we've reached the end of the charstring, simulate a */ |
| 559 /* cf2_cmdRETURN or cf2_cmdENDCHAR. */ | 556 /* cf2_cmdRETURN or cf2_cmdENDCHAR. */ |
| 560 if ( charstringIndex ) | 557 if ( charstringIndex ) |
| 561 op1 = cf2_cmdRETURN; /* end of buffer for subroutine */ | 558 op1 = cf2_cmdRETURN; /* end of buffer for subroutine */ |
| 562 else | 559 else |
| 563 op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */ | 560 op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */ |
| 564 } | 561 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 | 636 |
| 640 /* width is defined or default after this */ | 637 /* width is defined or default after this */ |
| 641 haveWidth = TRUE; | 638 haveWidth = TRUE; |
| 642 | 639 |
| 643 if ( font->decoder->width_only ) | 640 if ( font->decoder->width_only ) |
| 644 goto exit; | 641 goto exit; |
| 645 | 642 |
| 646 curY += cf2_stack_popFixed( opStack ); | 643 curY += cf2_stack_popFixed( opStack ); |
| 647 | 644 |
| 648 cf2_glyphpath_moveTo( &glyphPath, curX, curY ); | 645 cf2_glyphpath_moveTo( &glyphPath, curX, curY ); |
| 646 if (glyphPath.callbacks && glyphPath.callbacks->error && *glyphP
ath.callbacks->error) goto exit; |
| 649 | 647 |
| 650 break; | 648 break; |
| 651 | 649 |
| 652 case cf2_cmdRLINETO: | 650 case cf2_cmdRLINETO: |
| 653 { | 651 { |
| 654 CF2_UInt index; | 652 CF2_UInt index; |
| 655 CF2_UInt count = cf2_stack_count( opStack ); | 653 CF2_UInt count = cf2_stack_count( opStack ); |
| 656 | 654 |
| 657 | 655 |
| 658 FT_TRACE4(( " rlineto\n" )); | 656 FT_TRACE4(( " rlineto\n" )); |
| 659 | 657 |
| 660 for ( index = 0; index < count; index += 2 ) | 658 for ( index = 0; index < count; index += 2 ) |
| 661 { | 659 { |
| 662 curX += cf2_stack_getReal( opStack, index + 0 ); | 660 curX += cf2_stack_getReal( opStack, index + 0 ); |
| 663 curY += cf2_stack_getReal( opStack, index + 1 ); | 661 curY += cf2_stack_getReal( opStack, index + 1 ); |
| 664 | 662 |
| 665 cf2_glyphpath_lineTo( &glyphPath, curX, curY ); | 663 cf2_glyphpath_lineTo( &glyphPath, curX, curY ); |
| 664 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 666 } | 665 } |
| 667 | 666 |
| 668 cf2_stack_clear( opStack ); | 667 cf2_stack_clear( opStack ); |
| 669 } | 668 } |
| 670 continue; /* no need to clear stack again */ | 669 continue; /* no need to clear stack again */ |
| 671 | 670 |
| 672 case cf2_cmdHLINETO: | 671 case cf2_cmdHLINETO: |
| 673 case cf2_cmdVLINETO: | 672 case cf2_cmdVLINETO: |
| 674 { | 673 { |
| 675 CF2_UInt index; | 674 CF2_UInt index; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 686 | 685 |
| 687 | 686 |
| 688 if ( isX ) | 687 if ( isX ) |
| 689 curX += v; | 688 curX += v; |
| 690 else | 689 else |
| 691 curY += v; | 690 curY += v; |
| 692 | 691 |
| 693 isX = !isX; | 692 isX = !isX; |
| 694 | 693 |
| 695 cf2_glyphpath_lineTo( &glyphPath, curX, curY ); | 694 cf2_glyphpath_lineTo( &glyphPath, curX, curY ); |
| 695 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 696 } | 696 } |
| 697 | 697 |
| 698 cf2_stack_clear( opStack ); | 698 cf2_stack_clear( opStack ); |
| 699 } | 699 } |
| 700 continue; | 700 continue; |
| 701 | 701 |
| 702 case cf2_cmdRCURVELINE: | 702 case cf2_cmdRCURVELINE: |
| 703 case cf2_cmdRRCURVETO: | 703 case cf2_cmdRRCURVETO: |
| 704 { | 704 { |
| 705 CF2_UInt count = cf2_stack_count( opStack ); | 705 CF2_UInt count = cf2_stack_count( opStack ); |
| 706 CF2_UInt index = 0; | 706 CF2_UInt index = 0; |
| 707 | 707 |
| 708 | 708 |
| 709 FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n" | 709 FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n" |
| 710 : " rrcurveto\n" )); | 710 : " rrcurveto\n" )); |
| 711 | 711 |
| 712 while ( index + 6 <= count ) | 712 while ( index + 6 <= count ) |
| 713 { | 713 { |
| 714 CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; | 714 CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; |
| 715 CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY; | 715 CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY; |
| 716 CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1; | 716 CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1; |
| 717 CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1; | 717 CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1; |
| 718 CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; | 718 CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; |
| 719 CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2; | 719 CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2; |
| 720 | 720 |
| 721 | 721 |
| 722 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); | 722 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); |
| 723 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 723 | 724 |
| 724 curX = x3; | 725 curX = x3; |
| 725 curY = y3; | 726 curY = y3; |
| 726 index += 6; | 727 index += 6; |
| 727 } | 728 } |
| 728 | 729 |
| 729 if ( op1 == cf2_cmdRCURVELINE ) | 730 if ( op1 == cf2_cmdRCURVELINE ) |
| 730 { | 731 { |
| 731 curX += cf2_stack_getReal( opStack, index + 0 ); | 732 curX += cf2_stack_getReal( opStack, index + 0 ); |
| 732 curY += cf2_stack_getReal( opStack, index + 1 ); | 733 curY += cf2_stack_getReal( opStack, index + 1 ); |
| 733 | 734 |
| 734 cf2_glyphpath_lineTo( &glyphPath, curX, curY ); | 735 cf2_glyphpath_lineTo( &glyphPath, curX, curY ); |
| 736 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 735 } | 737 } |
| 736 | 738 |
| 737 cf2_stack_clear( opStack ); | 739 cf2_stack_clear( opStack ); |
| 738 } | 740 } |
| 739 continue; /* no need to clear stack again */ | 741 continue; /* no need to clear stack again */ |
| 740 | 742 |
| 741 case cf2_cmdCALLGSUBR: | 743 case cf2_cmdCALLGSUBR: |
| 742 case cf2_cmdCALLSUBR: | 744 case cf2_cmdCALLSUBR: |
| 743 { | 745 { |
| 744 CF2_UInt subrIndex; | 746 CF2_UInt subrIndex; |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1218 /* width is defined or default after this */ | 1220 /* width is defined or default after this */ |
| 1219 haveWidth = TRUE; | 1221 haveWidth = TRUE; |
| 1220 | 1222 |
| 1221 if ( font->decoder->width_only ) | 1223 if ( font->decoder->width_only ) |
| 1222 goto exit; | 1224 goto exit; |
| 1223 | 1225 |
| 1224 curY += cf2_stack_popFixed( opStack ); | 1226 curY += cf2_stack_popFixed( opStack ); |
| 1225 curX += cf2_stack_popFixed( opStack ); | 1227 curX += cf2_stack_popFixed( opStack ); |
| 1226 | 1228 |
| 1227 cf2_glyphpath_moveTo( &glyphPath, curX, curY ); | 1229 cf2_glyphpath_moveTo( &glyphPath, curX, curY ); |
| 1230 if (glyphPath.callbacks && glyphPath.callbacks->error && *glyphP
ath.callbacks->error) goto exit; |
| 1228 | 1231 |
| 1229 break; | 1232 break; |
| 1230 | 1233 |
| 1231 case cf2_cmdHMOVETO: | 1234 case cf2_cmdHMOVETO: |
| 1232 FT_TRACE4(( " hmoveto\n" )); | 1235 FT_TRACE4(( " hmoveto\n" )); |
| 1233 | 1236 |
| 1234 if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) | 1237 if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) |
| 1235 *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; | 1238 *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX; |
| 1236 | 1239 |
| 1237 /* width is defined or default after this */ | 1240 /* width is defined or default after this */ |
| 1238 haveWidth = TRUE; | 1241 haveWidth = TRUE; |
| 1239 | 1242 |
| 1240 if ( font->decoder->width_only ) | 1243 if ( font->decoder->width_only ) |
| 1241 goto exit; | 1244 goto exit; |
| 1242 | 1245 |
| 1243 curX += cf2_stack_popFixed( opStack ); | 1246 curX += cf2_stack_popFixed( opStack ); |
| 1244 | 1247 |
| 1245 cf2_glyphpath_moveTo( &glyphPath, curX, curY ); | 1248 cf2_glyphpath_moveTo( &glyphPath, curX, curY ); |
| 1249 if (glyphPath.callbacks && glyphPath.callbacks->error && *glyphP
ath.callbacks->error) goto exit; |
| 1246 | 1250 |
| 1247 break; | 1251 break; |
| 1248 | 1252 |
| 1249 case cf2_cmdRLINECURVE: | 1253 case cf2_cmdRLINECURVE: |
| 1250 { | 1254 { |
| 1251 CF2_UInt count = cf2_stack_count( opStack ); | 1255 CF2_UInt count = cf2_stack_count( opStack ); |
| 1252 CF2_UInt index = 0; | 1256 CF2_UInt index = 0; |
| 1253 | 1257 |
| 1254 | 1258 |
| 1255 FT_TRACE4(( " rlinecurve\n" )); | 1259 FT_TRACE4(( " rlinecurve\n" )); |
| 1256 | 1260 |
| 1257 while ( index + 6 < count ) | 1261 while ( index + 6 < count ) |
| 1258 { | 1262 { |
| 1259 curX += cf2_stack_getReal( opStack, index + 0 ); | 1263 curX += cf2_stack_getReal( opStack, index + 0 ); |
| 1260 curY += cf2_stack_getReal( opStack, index + 1 ); | 1264 curY += cf2_stack_getReal( opStack, index + 1 ); |
| 1261 | 1265 |
| 1262 cf2_glyphpath_lineTo( &glyphPath, curX, curY ); | 1266 cf2_glyphpath_lineTo( &glyphPath, curX, curY ); |
| 1267 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 1263 index += 2; | 1268 index += 2; |
| 1264 } | 1269 } |
| 1265 | 1270 |
| 1266 while ( index < count ) | 1271 while ( index < count ) |
| 1267 { | 1272 { |
| 1268 CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; | 1273 CF2_Fixed x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; |
| 1269 CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY; | 1274 CF2_Fixed y1 = cf2_stack_getReal( opStack, index + 1 ) + curY; |
| 1270 CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1; | 1275 CF2_Fixed x2 = cf2_stack_getReal( opStack, index + 2 ) + x1; |
| 1271 CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1; | 1276 CF2_Fixed y2 = cf2_stack_getReal( opStack, index + 3 ) + y1; |
| 1272 CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; | 1277 CF2_Fixed x3 = cf2_stack_getReal( opStack, index + 4 ) + x2; |
| 1273 CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2; | 1278 CF2_Fixed y3 = cf2_stack_getReal( opStack, index + 5 ) + y2; |
| 1274 | 1279 |
| 1275 | 1280 |
| 1276 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); | 1281 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); |
| 1282 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 1277 | 1283 |
| 1278 curX = x3; | 1284 curX = x3; |
| 1279 curY = y3; | 1285 curY = y3; |
| 1280 index += 6; | 1286 index += 6; |
| 1281 } | 1287 } |
| 1282 | 1288 |
| 1283 cf2_stack_clear( opStack ); | 1289 cf2_stack_clear( opStack ); |
| 1284 } | 1290 } |
| 1285 continue; /* no need to clear stack again */ | 1291 continue; /* no need to clear stack again */ |
| 1286 | 1292 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1306 else | 1312 else |
| 1307 x1 = curX; | 1313 x1 = curX; |
| 1308 | 1314 |
| 1309 y1 = cf2_stack_getReal( opStack, index + 0 ) + curY; | 1315 y1 = cf2_stack_getReal( opStack, index + 0 ) + curY; |
| 1310 x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; | 1316 x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; |
| 1311 y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; | 1317 y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; |
| 1312 x3 = x2; | 1318 x3 = x2; |
| 1313 y3 = cf2_stack_getReal( opStack, index + 3 ) + y2; | 1319 y3 = cf2_stack_getReal( opStack, index + 3 ) + y2; |
| 1314 | 1320 |
| 1315 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); | 1321 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); |
| 1322 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 1316 | 1323 |
| 1317 curX = x3; | 1324 curX = x3; |
| 1318 curY = y3; | 1325 curY = y3; |
| 1319 index += 4; | 1326 index += 4; |
| 1320 } | 1327 } |
| 1321 | 1328 |
| 1322 cf2_stack_clear( opStack ); | 1329 cf2_stack_clear( opStack ); |
| 1323 } | 1330 } |
| 1324 continue; /* no need to clear stack again */ | 1331 continue; /* no need to clear stack again */ |
| 1325 | 1332 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1345 else | 1352 else |
| 1346 y1 = curY; | 1353 y1 = curY; |
| 1347 | 1354 |
| 1348 x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; | 1355 x1 = cf2_stack_getReal( opStack, index + 0 ) + curX; |
| 1349 x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; | 1356 x2 = cf2_stack_getReal( opStack, index + 1 ) + x1; |
| 1350 y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; | 1357 y2 = cf2_stack_getReal( opStack, index + 2 ) + y1; |
| 1351 x3 = cf2_stack_getReal( opStack, index + 3 ) + x2; | 1358 x3 = cf2_stack_getReal( opStack, index + 3 ) + x2; |
| 1352 y3 = y2; | 1359 y3 = y2; |
| 1353 | 1360 |
| 1354 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); | 1361 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); |
| 1362 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 1355 | 1363 |
| 1356 curX = x3; | 1364 curX = x3; |
| 1357 curY = y3; | 1365 curY = y3; |
| 1358 index += 4; | 1366 index += 4; |
| 1359 } | 1367 } |
| 1360 | 1368 |
| 1361 cf2_stack_clear( opStack ); | 1369 cf2_stack_clear( opStack ); |
| 1362 } | 1370 } |
| 1363 continue; /* no need to clear stack again */ | 1371 continue; /* no need to clear stack again */ |
| 1364 | 1372 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 | 1419 |
| 1412 ++index; | 1420 ++index; |
| 1413 } | 1421 } |
| 1414 else | 1422 else |
| 1415 y3 = y2; | 1423 y3 = y2; |
| 1416 | 1424 |
| 1417 alternate = TRUE; | 1425 alternate = TRUE; |
| 1418 } | 1426 } |
| 1419 | 1427 |
| 1420 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); | 1428 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); |
| 1429 if (glyphPath.callbacks && glyphPath.callbacks->error &&
*glyphPath.callbacks->error) goto exit; |
| 1421 | 1430 |
| 1422 curX = x3; | 1431 curX = x3; |
| 1423 curY = y3; | 1432 curY = y3; |
| 1424 index += 4; | 1433 index += 4; |
| 1425 } | 1434 } |
| 1426 | 1435 |
| 1427 cf2_stack_clear( opStack ); | 1436 cf2_stack_clear( opStack ); |
| 1428 } | 1437 } |
| 1429 continue; /* no need to clear stack again */ | 1438 continue; /* no need to clear stack again */ |
| 1430 | 1439 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1531 cf2_arrstack_finalize( &subrStack ); | 1540 cf2_arrstack_finalize( &subrStack ); |
| 1532 cf2_stack_free( opStack ); | 1541 cf2_stack_free( opStack ); |
| 1533 | 1542 |
| 1534 FT_TRACE4(( "\n" )); | 1543 FT_TRACE4(( "\n" )); |
| 1535 | 1544 |
| 1536 return; | 1545 return; |
| 1537 } | 1546 } |
| 1538 | 1547 |
| 1539 | 1548 |
| 1540 /* END */ | 1549 /* END */ |
| OLD | NEW |