| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1998-2004 David Turner and Werner Lemberg | 2 * Copyright (C) 1998-2004 David Turner and Werner Lemberg |
| 3 * Copyright (C) 2006 Behdad Esfahbod | 3 * Copyright (C) 2006 Behdad Esfahbod |
| 4 * Copyright (C) 2007 Red Hat, Inc. | 4 * Copyright (C) 2007 Red Hat, Inc. |
| 5 * | 5 * |
| 6 * This is part of HarfBuzz, an OpenType Layout engine library. | 6 * This is part of HarfBuzz, an OpenType Layout engine library. |
| 7 * | 7 * |
| 8 * Permission is hereby granted, without written agreement and without | 8 * Permission is hereby granted, without written agreement and without |
| 9 * license or royalty fees, to use, copy, modify, and distribute this | 9 * license or royalty fees, to use, copy, modify, and distribute this |
| 10 * software and its documentation for any purpose, provided that the | 10 * software and its documentation for any purpose, provided that the |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 | 50 |
| 51 | 51 |
| 52 static HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi, | 52 static HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi, |
| 53 HB_UShort lookup_index, | 53 HB_UShort lookup_index, |
| 54 HB_Buffer buffer, | 54 HB_Buffer buffer, |
| 55 HB_UShort context_length, | 55 HB_UShort context_length, |
| 56 int nesting_level ); | 56 int nesting_level ); |
| 57 | 57 |
| 58 | 58 |
| 59 | 59 |
| 60 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 60 /* the client application must replace this with something more | 61 /* the client application must replace this with something more |
| 61 meaningful if multiple master fonts are to be supported. */ | 62 meaningful if multiple master fonts are to be supported. */ |
| 62 | 63 |
| 63 static HB_Error default_mmfunc( HB_Font font, | 64 static HB_Error default_mmfunc( HB_Font font, |
| 64 HB_UShort metric_id, | 65 HB_UShort metric_id, |
| 65 HB_Fixed* metric_value, | 66 HB_Fixed* metric_value, |
| 66 void* data ) | 67 void* data ) |
| 67 { | 68 { |
| 68 HB_UNUSED(font); | 69 HB_UNUSED(font); |
| 69 HB_UNUSED(metric_id); | 70 HB_UNUSED(metric_id); |
| 70 HB_UNUSED(metric_value); | 71 HB_UNUSED(metric_value); |
| 71 HB_UNUSED(data); | 72 HB_UNUSED(data); |
| 72 return ERR(HB_Err_Not_Covered); /* ERR() call intended */ | 73 return ERR(HB_Err_Not_Covered); /* ERR() call intended */ |
| 73 } | 74 } |
| 75 #endif |
| 74 | 76 |
| 75 | 77 |
| 76 | 78 |
| 77 HB_Error HB_Load_GPOS_Table( HB_Stream stream, | 79 HB_Error HB_Load_GPOS_Table( HB_Stream stream, |
| 78 HB_GPOSHeader** retptr, | 80 HB_GPOSHeader** retptr, |
| 79 HB_GDEFHeader* gdef, | 81 HB_GDEFHeader* gdef, |
| 80 HB_Stream gdefStream ) | 82 HB_Stream gdefStream ) |
| 81 { | 83 { |
| 82 HB_UInt cur_offset, new_offset, base_offset; | 84 HB_UInt cur_offset, new_offset, base_offset; |
| 83 | 85 |
| 84 HB_GPOSHeader* gpos; | 86 HB_GPOSHeader* gpos; |
| 85 | 87 |
| 86 HB_Error error; | 88 HB_Error error; |
| 87 | 89 |
| 88 | 90 |
| 89 if ( !retptr ) | 91 if ( !retptr ) |
| 90 return ERR(HB_Err_Invalid_Argument); | 92 return ERR(HB_Err_Invalid_Argument); |
| 91 | 93 |
| 92 if ( GOTO_Table( TTAG_GPOS ) ) | 94 if ( GOTO_Table( TTAG_GPOS ) ) |
| 93 return error; | 95 return error; |
| 94 | 96 |
| 95 base_offset = FILE_Pos(); | 97 base_offset = FILE_Pos(); |
| 96 | 98 |
| 97 if ( ALLOC ( gpos, sizeof( *gpos ) ) ) | 99 if ( ALLOC ( gpos, sizeof( *gpos ) ) ) |
| 98 return error; | 100 return error; |
| 99 | 101 |
| 102 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 100 gpos->mmfunc = default_mmfunc; | 103 gpos->mmfunc = default_mmfunc; |
| 104 #endif |
| 101 | 105 |
| 102 /* skip version */ | 106 /* skip version */ |
| 103 | 107 |
| 104 if ( FILE_Seek( base_offset + 4L ) || | 108 if ( FILE_Seek( base_offset + 4L ) || |
| 105 ACCESS_Frame( 2L ) ) | 109 ACCESS_Frame( 2L ) ) |
| 106 goto Fail4; | 110 goto Fail4; |
| 107 | 111 |
| 108 new_offset = GET_UShort() + base_offset; | 112 new_offset = GET_UShort() + base_offset; |
| 109 | 113 |
| 110 FORGET_Frame(); | 114 FORGET_Frame(); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 if ( ACCESS_Frame( 2L ) ) | 249 if ( ACCESS_Frame( 2L ) ) |
| 246 return error; | 250 return error; |
| 247 | 251 |
| 248 vr->YAdvance = GET_Short(); | 252 vr->YAdvance = GET_Short(); |
| 249 | 253 |
| 250 FORGET_Frame(); | 254 FORGET_Frame(); |
| 251 } | 255 } |
| 252 else | 256 else |
| 253 vr->YAdvance = 0; | 257 vr->YAdvance = 0; |
| 254 | 258 |
| 259 if ( format & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES ) |
| 260 { |
| 261 if ( ALLOC_ARRAY( vr->DeviceTables, 4, HB_Device ) ) |
| 262 return error; |
| 263 vr->DeviceTables[VR_X_ADVANCE_DEVICE] = 0; |
| 264 vr->DeviceTables[VR_Y_ADVANCE_DEVICE] = 0; |
| 265 vr->DeviceTables[VR_X_PLACEMENT_DEVICE] = 0; |
| 266 vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] = 0; |
| 267 } |
| 268 else |
| 269 { |
| 270 vr->DeviceTables = 0; |
| 271 } |
| 272 |
| 255 if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) | 273 if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) |
| 256 { | 274 { |
| 257 if ( ACCESS_Frame( 2L ) ) | 275 if ( ACCESS_Frame( 2L ) ) |
| 258 return error; | 276 goto Fail4; |
| 259 | 277 |
| 260 new_offset = GET_UShort(); | 278 new_offset = GET_UShort(); |
| 261 | 279 |
| 262 FORGET_Frame(); | 280 FORGET_Frame(); |
| 263 | 281 |
| 264 if ( new_offset ) | 282 if ( new_offset ) |
| 265 { | 283 { |
| 266 new_offset += base_offset; | 284 new_offset += base_offset; |
| 267 | 285 |
| 268 cur_offset = FILE_Pos(); | 286 cur_offset = FILE_Pos(); |
| 269 if ( FILE_Seek( new_offset ) || | 287 if ( FILE_Seek( new_offset ) || |
| 270 » ( error = _HB_OPEN_Load_Device( &vr->XPlacementDevice, | 288 » ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_PLACEMENT_DEVI
CE], |
| 271 stream ) ) != HB_Err_Ok ) | 289 stream ) ) != HB_Err_Ok ) |
| 272 » return error; | 290 goto Fail4; |
| 273 (void)FILE_Seek( cur_offset ); | 291 (void)FILE_Seek( cur_offset ); |
| 274 } | 292 } |
| 275 else | |
| 276 goto empty1; | |
| 277 } | |
| 278 else | |
| 279 { | |
| 280 empty1: | |
| 281 vr->XPlacementDevice.StartSize = 0; | |
| 282 vr->XPlacementDevice.EndSize = 0; | |
| 283 vr->XPlacementDevice.DeltaValue = NULL; | |
| 284 } | 293 } |
| 285 | 294 |
| 286 if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) | 295 if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) |
| 287 { | 296 { |
| 288 if ( ACCESS_Frame( 2L ) ) | 297 if ( ACCESS_Frame( 2L ) ) |
| 289 goto Fail3; | 298 goto Fail3; |
| 290 | 299 |
| 291 new_offset = GET_UShort(); | 300 new_offset = GET_UShort(); |
| 292 | 301 |
| 293 FORGET_Frame(); | 302 FORGET_Frame(); |
| 294 | 303 |
| 295 if ( new_offset ) | 304 if ( new_offset ) |
| 296 { | 305 { |
| 297 new_offset += base_offset; | 306 new_offset += base_offset; |
| 298 | 307 |
| 299 cur_offset = FILE_Pos(); | 308 cur_offset = FILE_Pos(); |
| 300 if ( FILE_Seek( new_offset ) || | 309 if ( FILE_Seek( new_offset ) || |
| 301 » ( error = _HB_OPEN_Load_Device( &vr->YPlacementDevice, | 310 » ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_PLACEMENT_DEVI
CE], |
| 302 stream ) ) != HB_Err_Ok ) | 311 stream ) ) != HB_Err_Ok ) |
| 303 goto Fail3; | 312 goto Fail3; |
| 304 (void)FILE_Seek( cur_offset ); | 313 (void)FILE_Seek( cur_offset ); |
| 305 } | 314 } |
| 306 else | |
| 307 goto empty2; | |
| 308 } | |
| 309 else | |
| 310 { | |
| 311 empty2: | |
| 312 vr->YPlacementDevice.StartSize = 0; | |
| 313 vr->YPlacementDevice.EndSize = 0; | |
| 314 vr->YPlacementDevice.DeltaValue = NULL; | |
| 315 } | 315 } |
| 316 | 316 |
| 317 if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) | 317 if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) |
| 318 { | 318 { |
| 319 if ( ACCESS_Frame( 2L ) ) | 319 if ( ACCESS_Frame( 2L ) ) |
| 320 goto Fail2; | 320 goto Fail2; |
| 321 | 321 |
| 322 new_offset = GET_UShort(); | 322 new_offset = GET_UShort(); |
| 323 | 323 |
| 324 FORGET_Frame(); | 324 FORGET_Frame(); |
| 325 | 325 |
| 326 if ( new_offset ) | 326 if ( new_offset ) |
| 327 { | 327 { |
| 328 new_offset += base_offset; | 328 new_offset += base_offset; |
| 329 | 329 |
| 330 cur_offset = FILE_Pos(); | 330 cur_offset = FILE_Pos(); |
| 331 if ( FILE_Seek( new_offset ) || | 331 if ( FILE_Seek( new_offset ) || |
| 332 » ( error = _HB_OPEN_Load_Device( &vr->XAdvanceDevice, | 332 » ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_ADVANCE_DEVICE
], |
| 333 stream ) ) != HB_Err_Ok ) | 333 stream ) ) != HB_Err_Ok ) |
| 334 goto Fail2; | 334 goto Fail2; |
| 335 (void)FILE_Seek( cur_offset ); | 335 (void)FILE_Seek( cur_offset ); |
| 336 } | 336 } |
| 337 else | |
| 338 goto empty3; | |
| 339 } | |
| 340 else | |
| 341 { | |
| 342 empty3: | |
| 343 vr->XAdvanceDevice.StartSize = 0; | |
| 344 vr->XAdvanceDevice.EndSize = 0; | |
| 345 vr->XAdvanceDevice.DeltaValue = NULL; | |
| 346 } | 337 } |
| 347 | 338 |
| 348 if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) | 339 if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) |
| 349 { | 340 { |
| 350 if ( ACCESS_Frame( 2L ) ) | 341 if ( ACCESS_Frame( 2L ) ) |
| 351 goto Fail1; | 342 goto Fail1; |
| 352 | 343 |
| 353 new_offset = GET_UShort(); | 344 new_offset = GET_UShort(); |
| 354 | 345 |
| 355 FORGET_Frame(); | 346 FORGET_Frame(); |
| 356 | 347 |
| 357 if ( new_offset ) | 348 if ( new_offset ) |
| 358 { | 349 { |
| 359 new_offset += base_offset; | 350 new_offset += base_offset; |
| 360 | 351 |
| 361 cur_offset = FILE_Pos(); | 352 cur_offset = FILE_Pos(); |
| 362 if ( FILE_Seek( new_offset ) || | 353 if ( FILE_Seek( new_offset ) || |
| 363 » ( error = _HB_OPEN_Load_Device( &vr->YAdvanceDevice, | 354 » ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_ADVANCE_DEVICE
], |
| 364 stream ) ) != HB_Err_Ok ) | 355 stream ) ) != HB_Err_Ok ) |
| 365 goto Fail1; | 356 goto Fail1; |
| 366 (void)FILE_Seek( cur_offset ); | 357 (void)FILE_Seek( cur_offset ); |
| 367 } | 358 } |
| 368 else | |
| 369 goto empty4; | |
| 370 } | |
| 371 else | |
| 372 { | |
| 373 empty4: | |
| 374 vr->YAdvanceDevice.StartSize = 0; | |
| 375 vr->YAdvanceDevice.EndSize = 0; | |
| 376 vr->YAdvanceDevice.DeltaValue = NULL; | |
| 377 } | 359 } |
| 378 | 360 |
| 379 if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT ) | 361 if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT ) |
| 380 { | 362 { |
| 381 if ( ACCESS_Frame( 2L ) ) | 363 if ( ACCESS_Frame( 2L ) ) |
| 382 goto Fail1; | 364 goto Fail1; |
| 383 | 365 |
| 366 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 384 vr->XIdPlacement = GET_UShort(); | 367 vr->XIdPlacement = GET_UShort(); |
| 368 #else |
| 369 (void) GET_UShort(); |
| 370 #endif |
| 385 | 371 |
| 386 FORGET_Frame(); | 372 FORGET_Frame(); |
| 387 } | 373 } |
| 374 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 388 else | 375 else |
| 389 vr->XIdPlacement = 0; | 376 vr->XIdPlacement = 0; |
| 377 #endif |
| 390 | 378 |
| 391 if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT ) | 379 if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT ) |
| 392 { | 380 { |
| 393 if ( ACCESS_Frame( 2L ) ) | 381 if ( ACCESS_Frame( 2L ) ) |
| 394 goto Fail1; | 382 goto Fail1; |
| 395 | 383 |
| 384 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 396 vr->YIdPlacement = GET_UShort(); | 385 vr->YIdPlacement = GET_UShort(); |
| 386 #else |
| 387 (void) GET_UShort(); |
| 388 #endif |
| 397 | 389 |
| 398 FORGET_Frame(); | 390 FORGET_Frame(); |
| 399 } | 391 } |
| 392 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 400 else | 393 else |
| 401 vr->YIdPlacement = 0; | 394 vr->YIdPlacement = 0; |
| 395 #endif |
| 402 | 396 |
| 403 if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE ) | 397 if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE ) |
| 404 { | 398 { |
| 405 if ( ACCESS_Frame( 2L ) ) | 399 if ( ACCESS_Frame( 2L ) ) |
| 406 goto Fail1; | 400 goto Fail1; |
| 407 | 401 |
| 402 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 408 vr->XIdAdvance = GET_UShort(); | 403 vr->XIdAdvance = GET_UShort(); |
| 404 #else |
| 405 (void) GET_UShort(); |
| 406 #endif |
| 409 | 407 |
| 410 FORGET_Frame(); | 408 FORGET_Frame(); |
| 411 } | 409 } |
| 410 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 412 else | 411 else |
| 413 vr->XIdAdvance = 0; | 412 vr->XIdAdvance = 0; |
| 413 #endif |
| 414 | 414 |
| 415 if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE ) | 415 if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE ) |
| 416 { | 416 { |
| 417 if ( ACCESS_Frame( 2L ) ) | 417 if ( ACCESS_Frame( 2L ) ) |
| 418 goto Fail1; | 418 goto Fail1; |
| 419 | 419 |
| 420 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 420 vr->YIdAdvance = GET_UShort(); | 421 vr->YIdAdvance = GET_UShort(); |
| 422 #else |
| 423 (void) GET_UShort(); |
| 424 #endif |
| 421 | 425 |
| 422 FORGET_Frame(); | 426 FORGET_Frame(); |
| 423 } | 427 } |
| 428 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 424 else | 429 else |
| 425 vr->YIdAdvance = 0; | 430 vr->YIdAdvance = 0; |
| 431 #endif |
| 426 | 432 |
| 427 return HB_Err_Ok; | 433 return HB_Err_Ok; |
| 428 | 434 |
| 429 Fail1: | 435 Fail1: |
| 430 _HB_OPEN_Free_Device( &vr->YAdvanceDevice ); | 436 if ( vr->DeviceTables ) |
| 437 _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] ); |
| 431 | 438 |
| 432 Fail2: | 439 Fail2: |
| 433 _HB_OPEN_Free_Device( &vr->XAdvanceDevice ); | 440 if ( vr->DeviceTables ) |
| 441 _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] ); |
| 434 | 442 |
| 435 Fail3: | 443 Fail3: |
| 436 _HB_OPEN_Free_Device( &vr->YPlacementDevice ); | 444 if ( vr->DeviceTables ) |
| 445 _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] ); |
| 446 |
| 447 Fail4: |
| 448 FREE( vr->DeviceTables ); |
| 437 return error; | 449 return error; |
| 438 } | 450 } |
| 439 | 451 |
| 440 | 452 |
| 441 static void Free_ValueRecord( HB_ValueRecord* vr, | 453 static void Free_ValueRecord( HB_ValueRecord* vr, |
| 442 HB_UShort format ) | 454 HB_UShort format ) |
| 443 { | 455 { |
| 444 if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) | 456 if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) |
| 445 _HB_OPEN_Free_Device( &vr->YAdvanceDevice ); | 457 _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] ); |
| 446 if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) | 458 if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) |
| 447 _HB_OPEN_Free_Device( &vr->XAdvanceDevice ); | 459 _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] ); |
| 448 if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) | 460 if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) |
| 449 _HB_OPEN_Free_Device( &vr->YPlacementDevice ); | 461 _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] ); |
| 450 if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) | 462 if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) |
| 451 _HB_OPEN_Free_Device( &vr->XPlacementDevice ); | 463 _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE] ); |
| 464 FREE( vr->DeviceTables ); |
| 452 } | 465 } |
| 453 | 466 |
| 454 | 467 |
| 455 static HB_Error Get_ValueRecord( GPOS_Instance* gpi, | 468 static HB_Error Get_ValueRecord( GPOS_Instance* gpi, |
| 456 HB_ValueRecord* vr, | 469 HB_ValueRecord* vr, |
| 457 HB_UShort format, | 470 HB_UShort format, |
| 458 HB_Position gd ) | 471 HB_Position gd ) |
| 459 { | 472 { |
| 460 HB_Fixed value; | |
| 461 HB_Short pixel_value; | 473 HB_Short pixel_value; |
| 462 HB_Error error = HB_Err_Ok; | 474 HB_Error error = HB_Err_Ok; |
| 475 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 463 HB_GPOSHeader* gpos = gpi->gpos; | 476 HB_GPOSHeader* gpos = gpi->gpos; |
| 477 HB_Fixed value; |
| 478 #endif |
| 464 | 479 |
| 465 HB_UShort x_ppem, y_ppem; | 480 HB_UShort x_ppem, y_ppem; |
| 466 HB_16Dot16 x_scale, y_scale; | 481 HB_16Dot16 x_scale, y_scale; |
| 467 | 482 |
| 468 | 483 |
| 469 if ( !format ) | 484 if ( !format ) |
| 470 return HB_Err_Ok; | 485 return HB_Err_Ok; |
| 471 | 486 |
| 472 x_ppem = gpi->font->x_ppem; | 487 x_ppem = gpi->font->x_ppem; |
| 473 y_ppem = gpi->font->y_ppem; | 488 y_ppem = gpi->font->y_ppem; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 484 gd->x_advance += x_scale * vr->XAdvance / 0x10000; | 499 gd->x_advance += x_scale * vr->XAdvance / 0x10000; |
| 485 if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE ) | 500 if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE ) |
| 486 gd->y_advance += y_scale * vr->YAdvance / 0x10000; | 501 gd->y_advance += y_scale * vr->YAdvance / 0x10000; |
| 487 | 502 |
| 488 if ( !gpi->dvi ) | 503 if ( !gpi->dvi ) |
| 489 { | 504 { |
| 490 /* pixel -> fractional pixel */ | 505 /* pixel -> fractional pixel */ |
| 491 | 506 |
| 492 if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) | 507 if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) |
| 493 { | 508 { |
| 494 _HB_OPEN_Get_Device( &vr->XPlacementDevice, x_ppem, &pixel_value ); | 509 _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE], x_ppem, &pix
el_value ); |
| 495 gd->x_pos += pixel_value << 6; | 510 gd->x_pos += pixel_value << 6; |
| 496 } | 511 } |
| 497 if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) | 512 if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) |
| 498 { | 513 { |
| 499 _HB_OPEN_Get_Device( &vr->YPlacementDevice, y_ppem, &pixel_value ); | 514 _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE], y_ppem, &pix
el_value ); |
| 500 gd->y_pos += pixel_value << 6; | 515 gd->y_pos += pixel_value << 6; |
| 501 } | 516 } |
| 502 if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) | 517 if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) |
| 503 { | 518 { |
| 504 _HB_OPEN_Get_Device( &vr->XAdvanceDevice, x_ppem, &pixel_value ); | 519 _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE], x_ppem, &pixel
_value ); |
| 505 gd->x_advance += pixel_value << 6; | 520 gd->x_advance += pixel_value << 6; |
| 506 } | 521 } |
| 507 if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) | 522 if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) |
| 508 { | 523 { |
| 509 _HB_OPEN_Get_Device( &vr->YAdvanceDevice, y_ppem, &pixel_value ); | 524 _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE], y_ppem, &pixel
_value ); |
| 510 gd->y_advance += pixel_value << 6; | 525 gd->y_advance += pixel_value << 6; |
| 511 } | 526 } |
| 512 } | 527 } |
| 513 | 528 |
| 529 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 514 /* values returned from mmfunc() are already in fractional pixels */ | 530 /* values returned from mmfunc() are already in fractional pixels */ |
| 515 | 531 |
| 516 if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT ) | 532 if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT ) |
| 517 { | 533 { |
| 518 error = (gpos->mmfunc)( gpi->font, vr->XIdPlacement, | 534 error = (gpos->mmfunc)( gpi->font, vr->XIdPlacement, |
| 519 &value, gpos->data ); | 535 &value, gpos->data ); |
| 520 if ( error ) | 536 if ( error ) |
| 521 return error; | 537 return error; |
| 522 gd->x_pos += value; | 538 gd->x_pos += value; |
| 523 } | 539 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 538 gd->x_advance += value; | 554 gd->x_advance += value; |
| 539 } | 555 } |
| 540 if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE ) | 556 if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE ) |
| 541 { | 557 { |
| 542 error = (gpos->mmfunc)( gpi->font, vr->YIdAdvance, | 558 error = (gpos->mmfunc)( gpi->font, vr->YIdAdvance, |
| 543 &value, gpos->data ); | 559 &value, gpos->data ); |
| 544 if ( error ) | 560 if ( error ) |
| 545 return error; | 561 return error; |
| 546 gd->y_advance += value; | 562 gd->y_advance += value; |
| 547 } | 563 } |
| 564 #endif |
| 548 | 565 |
| 549 return error; | 566 return error; |
| 550 } | 567 } |
| 551 | 568 |
| 552 | 569 |
| 553 /* AnchorFormat1 */ | 570 /* AnchorFormat1 */ |
| 554 /* AnchorFormat2 */ | 571 /* AnchorFormat2 */ |
| 555 /* AnchorFormat3 */ | 572 /* AnchorFormat3 */ |
| 556 /* AnchorFormat4 */ | 573 /* AnchorFormat4 */ |
| 557 | 574 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 | 618 |
| 602 an->af.af3.XCoordinate = GET_Short(); | 619 an->af.af3.XCoordinate = GET_Short(); |
| 603 an->af.af3.YCoordinate = GET_Short(); | 620 an->af.af3.YCoordinate = GET_Short(); |
| 604 | 621 |
| 605 new_offset = GET_UShort(); | 622 new_offset = GET_UShort(); |
| 606 | 623 |
| 607 FORGET_Frame(); | 624 FORGET_Frame(); |
| 608 | 625 |
| 609 if ( new_offset ) | 626 if ( new_offset ) |
| 610 { | 627 { |
| 628 if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) ) |
| 629 return error; |
| 630 |
| 631 an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0; |
| 632 an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0; |
| 633 |
| 611 new_offset += base_offset; | 634 new_offset += base_offset; |
| 612 | 635 |
| 613 cur_offset = FILE_Pos(); | 636 cur_offset = FILE_Pos(); |
| 614 if ( FILE_Seek( new_offset ) || | 637 if ( FILE_Seek( new_offset ) || |
| 615 » ( error = _HB_OPEN_Load_Device( &an->af.af3.XDeviceTable, | 638 » ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_X_DEVICE
_TABLE], |
| 616 stream ) ) != HB_Err_Ok ) | 639 stream ) ) != HB_Err_Ok ) |
| 617 » return error; | 640 » goto Fail2; |
| 618 (void)FILE_Seek( cur_offset ); | 641 (void)FILE_Seek( cur_offset ); |
| 619 } | 642 } |
| 620 else | |
| 621 { | |
| 622 an->af.af3.XDeviceTable.StartSize = 0; | |
| 623 an->af.af3.XDeviceTable.EndSize = 0; | |
| 624 an->af.af3.XDeviceTable.DeltaValue = NULL; | |
| 625 } | |
| 626 | 643 |
| 627 if ( ACCESS_Frame( 2L ) ) | 644 if ( ACCESS_Frame( 2L ) ) |
| 628 goto Fail; | 645 goto Fail; |
| 629 | 646 |
| 630 new_offset = GET_UShort(); | 647 new_offset = GET_UShort(); |
| 631 | 648 |
| 632 FORGET_Frame(); | 649 FORGET_Frame(); |
| 633 | 650 |
| 634 if ( new_offset ) | 651 if ( new_offset ) |
| 635 { | 652 { |
| 653 if ( !an->af.af3.DeviceTables ) |
| 654 { |
| 655 if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) ) |
| 656 return error; |
| 657 |
| 658 an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0; |
| 659 an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0; |
| 660 } |
| 661 |
| 636 new_offset += base_offset; | 662 new_offset += base_offset; |
| 637 | 663 |
| 638 cur_offset = FILE_Pos(); | 664 cur_offset = FILE_Pos(); |
| 639 if ( FILE_Seek( new_offset ) || | 665 if ( FILE_Seek( new_offset ) || |
| 640 » ( error = _HB_OPEN_Load_Device( &an->af.af3.YDeviceTable, | 666 » ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_Y_DEVICE
_TABLE], |
| 641 stream ) ) != HB_Err_Ok ) | 667 stream ) ) != HB_Err_Ok ) |
| 642 goto Fail; | 668 goto Fail; |
| 643 (void)FILE_Seek( cur_offset ); | 669 (void)FILE_Seek( cur_offset ); |
| 644 } | 670 } |
| 645 else | |
| 646 { | |
| 647 an->af.af3.YDeviceTable.StartSize = 0; | |
| 648 an->af.af3.YDeviceTable.EndSize = 0; | |
| 649 an->af.af3.YDeviceTable.DeltaValue = NULL; | |
| 650 } | |
| 651 break; | 671 break; |
| 652 | 672 |
| 653 case 4: | 673 case 4: |
| 654 if ( ACCESS_Frame( 4L ) ) | 674 if ( ACCESS_Frame( 4L ) ) |
| 655 return error; | 675 return error; |
| 656 | 676 |
| 677 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 657 an->af.af4.XIdAnchor = GET_UShort(); | 678 an->af.af4.XIdAnchor = GET_UShort(); |
| 658 an->af.af4.YIdAnchor = GET_UShort(); | 679 an->af.af4.YIdAnchor = GET_UShort(); |
| 680 #else |
| 681 (void) GET_UShort(); |
| 682 (void) GET_UShort(); |
| 683 #endif |
| 659 | 684 |
| 660 FORGET_Frame(); | 685 FORGET_Frame(); |
| 661 break; | 686 break; |
| 662 | 687 |
| 663 default: | 688 default: |
| 664 return ERR(HB_Err_Invalid_SubTable_Format); | 689 return ERR(HB_Err_Invalid_SubTable_Format); |
| 665 } | 690 } |
| 666 | 691 |
| 667 return HB_Err_Ok; | 692 return HB_Err_Ok; |
| 668 | 693 |
| 669 Fail: | 694 Fail: |
| 670 _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable ); | 695 if ( an->af.af3.DeviceTables ) |
| 696 _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] ); |
| 697 |
| 698 Fail2: |
| 699 FREE( an->af.af3.DeviceTables ); |
| 671 return error; | 700 return error; |
| 672 } | 701 } |
| 673 | 702 |
| 674 | 703 |
| 675 static void Free_Anchor( HB_Anchor* an) | 704 static void Free_Anchor( HB_Anchor* an) |
| 676 { | 705 { |
| 677 if ( an->PosFormat == 3 ) | 706 if ( an->PosFormat == 3 && an->af.af3.DeviceTables ) |
| 678 { | 707 { |
| 679 _HB_OPEN_Free_Device( &an->af.af3.YDeviceTable ); | 708 _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] ); |
| 680 _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable ); | 709 _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] ); |
| 710 FREE( an->af.af3.DeviceTables ); |
| 681 } | 711 } |
| 682 } | 712 } |
| 683 | 713 |
| 684 | 714 |
| 685 static HB_Error Get_Anchor( GPOS_Instance* gpi, | 715 static HB_Error Get_Anchor( GPOS_Instance* gpi, |
| 686 HB_Anchor* an, | 716 HB_Anchor* an, |
| 687 HB_UShort glyph_index, | 717 HB_UShort glyph_index, |
| 688 HB_Fixed* x_value, | 718 HB_Fixed* x_value, |
| 689 HB_Fixed* y_value ) | 719 HB_Fixed* y_value ) |
| 690 { | 720 { |
| 691 HB_Error error = HB_Err_Ok; | 721 HB_Error error = HB_Err_Ok; |
| 692 | 722 |
| 723 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 693 HB_GPOSHeader* gpos = gpi->gpos; | 724 HB_GPOSHeader* gpos = gpi->gpos; |
| 725 #endif |
| 694 HB_UShort ap; | 726 HB_UShort ap; |
| 695 | 727 |
| 696 HB_Short pixel_value; | 728 HB_Short pixel_value; |
| 697 | 729 |
| 698 HB_UShort x_ppem, y_ppem; | 730 HB_UShort x_ppem, y_ppem; |
| 699 HB_16Dot16 x_scale, y_scale; | 731 HB_16Dot16 x_scale, y_scale; |
| 700 | 732 |
| 701 | 733 |
| 702 x_ppem = gpi->font->x_ppem; | 734 x_ppem = gpi->font->x_ppem; |
| 703 y_ppem = gpi->font->y_ppem; | 735 y_ppem = gpi->font->y_ppem; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 { | 768 { |
| 737 no_contour_point: | 769 no_contour_point: |
| 738 *x_value = x_scale * an->af.af3.XCoordinate / 0x10000; | 770 *x_value = x_scale * an->af.af3.XCoordinate / 0x10000; |
| 739 *y_value = y_scale * an->af.af3.YCoordinate / 0x10000; | 771 *y_value = y_scale * an->af.af3.YCoordinate / 0x10000; |
| 740 } | 772 } |
| 741 break; | 773 break; |
| 742 | 774 |
| 743 case 3: | 775 case 3: |
| 744 if ( !gpi->dvi ) | 776 if ( !gpi->dvi ) |
| 745 { | 777 { |
| 746 _HB_OPEN_Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value ); | 778 _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE], x_ppem,
&pixel_value ); |
| 747 *x_value = pixel_value << 6; | 779 *x_value = pixel_value << 6; |
| 748 _HB_OPEN_Get_Device( &an->af.af3.YDeviceTable, y_ppem, &pixel_value ); | 780 _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE], y_ppem,
&pixel_value ); |
| 749 *y_value = pixel_value << 6; | 781 *y_value = pixel_value << 6; |
| 750 } | 782 } |
| 751 else | 783 else |
| 752 *x_value = *y_value = 0; | 784 *x_value = *y_value = 0; |
| 753 | 785 |
| 754 *x_value += x_scale * an->af.af3.XCoordinate / 0x10000; | 786 *x_value += x_scale * an->af.af3.XCoordinate / 0x10000; |
| 755 *y_value += y_scale * an->af.af3.YCoordinate / 0x10000; | 787 *y_value += y_scale * an->af.af3.YCoordinate / 0x10000; |
| 756 break; | 788 break; |
| 757 | 789 |
| 758 case 4: | 790 case 4: |
| 791 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 759 error = (gpos->mmfunc)( gpi->font, an->af.af4.XIdAnchor, | 792 error = (gpos->mmfunc)( gpi->font, an->af.af4.XIdAnchor, |
| 760 x_value, gpos->data ); | 793 x_value, gpos->data ); |
| 761 if ( error ) | 794 if ( error ) |
| 762 return error; | 795 return error; |
| 763 | 796 |
| 764 error = (gpos->mmfunc)( gpi->font, an->af.af4.YIdAnchor, | 797 error = (gpos->mmfunc)( gpi->font, an->af.af4.YIdAnchor, |
| 765 y_value, gpos->data ); | 798 y_value, gpos->data ); |
| 766 if ( error ) | 799 if ( error ) |
| 767 return error; | 800 return error; |
| 768 break; | 801 break; |
| 802 #else |
| 803 return ERR(HB_Err_Not_Covered); |
| 804 #endif |
| 769 } | 805 } |
| 770 | 806 |
| 771 return error; | 807 return error; |
| 772 } | 808 } |
| 773 | 809 |
| 774 | 810 |
| 775 /* MarkArray */ | 811 /* MarkArray */ |
| 776 | 812 |
| 777 static HB_Error Load_MarkArray ( HB_MarkArray* ma, | 813 static HB_Error Load_MarkArray ( HB_MarkArray* ma, |
| 778 HB_Stream stream ) | 814 HB_Stream stream ) |
| (...skipping 5183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5962 gpos->FeatureList.ApplyCount = 0; | 5998 gpos->FeatureList.ApplyCount = 0; |
| 5963 | 5999 |
| 5964 properties = gpos->LookupList.Properties; | 6000 properties = gpos->LookupList.Properties; |
| 5965 | 6001 |
| 5966 for ( i = 0; i < gpos->LookupList.LookupCount; i++ ) | 6002 for ( i = 0; i < gpos->LookupList.LookupCount; i++ ) |
| 5967 properties[i] = 0; | 6003 properties[i] = 0; |
| 5968 | 6004 |
| 5969 return HB_Err_Ok; | 6005 return HB_Err_Ok; |
| 5970 } | 6006 } |
| 5971 | 6007 |
| 5972 | 6008 #ifdef HB_SUPPORT_MULTIPLE_MASTER |
| 5973 | |
| 5974 HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos, | 6009 HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos, |
| 5975 HB_MMFunction mmfunc, | 6010 HB_MMFunction mmfunc, |
| 5976 void* data ) | 6011 void* data ) |
| 5977 { | 6012 { |
| 5978 if ( !gpos ) | 6013 if ( !gpos ) |
| 5979 return ERR(HB_Err_Invalid_Argument); | 6014 return ERR(HB_Err_Invalid_Argument); |
| 5980 | 6015 |
| 5981 gpos->mmfunc = mmfunc; | 6016 gpos->mmfunc = mmfunc; |
| 5982 gpos->data = data; | 6017 gpos->data = data; |
| 5983 | 6018 |
| 5984 return HB_Err_Ok; | 6019 return HB_Err_Ok; |
| 5985 } | 6020 } |
| 6021 #endif |
| 5986 | 6022 |
| 5987 /* If `dvi' is TRUE, glyph contour points for anchor points and device | 6023 /* If `dvi' is TRUE, glyph contour points for anchor points and device |
| 5988 tables are ignored -- you will get device independent values. */ | 6024 tables are ignored -- you will get device independent values. */ |
| 5989 | 6025 |
| 5990 | 6026 |
| 5991 HB_Error HB_GPOS_Apply_String( HB_Font font, | 6027 HB_Error HB_GPOS_Apply_String( HB_Font font, |
| 5992 HB_GPOSHeader* gpos, | 6028 HB_GPOSHeader* gpos, |
| 5993 HB_UShort load_flags, | 6029 HB_UShort load_flags, |
| 5994 HB_Buffer buffer, | 6030 HB_Buffer buffer, |
| 5995 HB_Bool dvi, | 6031 HB_Bool dvi, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6049 { | 6085 { |
| 6050 error = Position_CursiveChain ( buffer ); | 6086 error = Position_CursiveChain ( buffer ); |
| 6051 if ( error ) | 6087 if ( error ) |
| 6052 return error; | 6088 return error; |
| 6053 } | 6089 } |
| 6054 | 6090 |
| 6055 return retError; | 6091 return retError; |
| 6056 } | 6092 } |
| 6057 | 6093 |
| 6058 /* END */ | 6094 /* END */ |
| OLD | NEW |