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 |