00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <ft2build.h>
00019 #include FT_INTERNAL_DEBUG_H
00020 #include FT_INTERNAL_STREAM_H
00021 #include FT_TRUETYPE_TAGS_H
00022
00023
00024
00025
00026
00027 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
00028
00029 #include "ttsbit0.c"
00030
00031 #else
00032
00033 #include <ft2build.h>
00034 #include FT_INTERNAL_DEBUG_H
00035 #include FT_INTERNAL_STREAM_H
00036 #include FT_TRUETYPE_TAGS_H
00037 #include "ttsbit.h"
00038
00039 #include "sferrors.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048 #undef FT_COMPONENT
00049 #define FT_COMPONENT trace_ttsbit
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 static void
00081 blit_sbit( FT_Bitmap* target,
00082 FT_Byte* source,
00083 FT_Int line_bits,
00084 FT_Bool byte_padded,
00085 FT_Int x_offset,
00086 FT_Int y_offset,
00087 FT_Int source_height )
00088 {
00089 FT_Byte* line_buff;
00090 FT_Int line_incr;
00091 FT_Int height;
00092
00093 FT_UShort acc;
00094 FT_UInt loaded;
00095
00096
00097
00098 line_incr = target->pitch;
00099 line_buff = target->buffer;
00100
00101 if ( line_incr < 0 )
00102 line_buff -= line_incr * ( target->rows - 1 );
00103
00104 line_buff += ( x_offset >> 3 ) + y_offset * line_incr;
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 acc = 0;
00118 loaded = 0;
00119
00120 for ( height = source_height; height > 0; height-- )
00121 {
00122 FT_Byte* cur = line_buff;
00123 FT_Int count = line_bits;
00124 FT_Byte shift = (FT_Byte)( x_offset & 7 );
00125 FT_Byte space = (FT_Byte)( 8 - shift );
00126
00127
00128
00129 if ( count >= 8 )
00130 {
00131 count -= 8;
00132 {
00133 do
00134 {
00135 FT_Byte val;
00136
00137
00138
00139 if ( loaded < 8 )
00140 {
00141 acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
00142 loaded += 8;
00143 }
00144
00145
00146 val = (FT_Byte)( acc >> 8 );
00147 if ( shift )
00148 {
00149 cur[0] |= (FT_Byte)( val >> shift );
00150 cur[1] |= (FT_Byte)( val << space );
00151 }
00152 else
00153 cur[0] |= val;
00154
00155 cur++;
00156 acc <<= 8;
00157 loaded -= 8;
00158 count -= 8;
00159
00160 } while ( count >= 0 );
00161 }
00162
00163
00164 count += 8;
00165 }
00166
00167
00168 if ( count > 0 )
00169 {
00170 FT_Byte val;
00171
00172
00173
00174 if ( (FT_Int)loaded < count )
00175 {
00176 acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
00177 loaded += 8;
00178 }
00179
00180
00181 val = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
00182 cur[0] |= (FT_Byte)( val >> shift );
00183
00184 if ( count > space )
00185 cur[1] |= (FT_Byte)( val << space );
00186
00187 acc <<= count;
00188 loaded -= count;
00189 }
00190
00191
00192 if ( byte_padded )
00193 {
00194 acc = 0;
00195 loaded = 0;
00196 }
00197
00198 line_buff += line_incr;
00199 }
00200 }
00201
00202
00203 static const FT_Frame_Field sbit_metrics_fields[] =
00204 {
00205 #undef FT_STRUCTURE
00206 #define FT_STRUCTURE TT_SBit_MetricsRec
00207
00208 FT_FRAME_START( 8 ),
00209 FT_FRAME_BYTE( height ),
00210 FT_FRAME_BYTE( width ),
00211
00212 FT_FRAME_CHAR( horiBearingX ),
00213 FT_FRAME_CHAR( horiBearingY ),
00214 FT_FRAME_BYTE( horiAdvance ),
00215
00216 FT_FRAME_CHAR( vertBearingX ),
00217 FT_FRAME_CHAR( vertBearingY ),
00218 FT_FRAME_BYTE( vertAdvance ),
00219 FT_FRAME_END
00220 };
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 static FT_Error
00240 Load_SBit_Const_Metrics( TT_SBit_Range range,
00241 FT_Stream stream )
00242 {
00243 FT_Error error;
00244
00245
00246 if ( FT_READ_ULONG( range->image_size ) )
00247 return error;
00248
00249 return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics );
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 static FT_Error
00272 Load_SBit_Range_Codes( TT_SBit_Range range,
00273 FT_Stream stream,
00274 FT_Bool load_offsets )
00275 {
00276 FT_Error error;
00277 FT_ULong count, n, size;
00278 FT_Memory memory = stream->memory;
00279
00280
00281 if ( FT_READ_ULONG( count ) )
00282 goto Exit;
00283
00284 range->num_glyphs = count;
00285
00286
00287 if ( load_offsets )
00288 {
00289 if ( FT_NEW_ARRAY( range->glyph_offsets, count ) )
00290 goto Exit;
00291
00292 size = count * 4L;
00293 }
00294 else
00295 size = count * 2L;
00296
00297
00298 if ( FT_NEW_ARRAY ( range->glyph_codes, count ) ||
00299 FT_FRAME_ENTER( size ) )
00300 goto Exit;
00301
00302 for ( n = 0; n < count; n++ )
00303 {
00304 range->glyph_codes[n] = FT_GET_USHORT();
00305
00306 if ( load_offsets )
00307 range->glyph_offsets[n] = (FT_ULong)range->image_offset +
00308 FT_GET_USHORT();
00309 }
00310
00311 FT_FRAME_EXIT();
00312
00313 Exit:
00314 return error;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 static FT_Error
00335 Load_SBit_Range( TT_SBit_Range range,
00336 FT_Stream stream )
00337 {
00338 FT_Error error;
00339 FT_Memory memory = stream->memory;
00340
00341
00342 switch( range->index_format )
00343 {
00344 case 1:
00345 case 3:
00346 {
00347 FT_ULong num_glyphs, n;
00348 FT_Int size_elem;
00349 FT_Bool large = FT_BOOL( range->index_format == 1 );
00350
00351
00352
00353 if ( range->last_glyph < range->first_glyph )
00354 {
00355 error = SFNT_Err_Invalid_File_Format;
00356 goto Exit;
00357 }
00358
00359 num_glyphs = range->last_glyph - range->first_glyph + 1L;
00360 range->num_glyphs = num_glyphs;
00361 num_glyphs++;
00362
00363 size_elem = large ? 4 : 2;
00364
00365 if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) ||
00366 FT_FRAME_ENTER( num_glyphs * size_elem ) )
00367 goto Exit;
00368
00369 for ( n = 0; n < num_glyphs; n++ )
00370 range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
00371 ( large ? FT_GET_ULONG()
00372 : FT_GET_USHORT() ) );
00373 FT_FRAME_EXIT();
00374 }
00375 break;
00376
00377 case 2:
00378 error = Load_SBit_Const_Metrics( range, stream );
00379 break;
00380
00381 case 4:
00382 error = Load_SBit_Range_Codes( range, stream, 1 );
00383 break;
00384
00385 case 5:
00386 error = Load_SBit_Const_Metrics( range, stream );
00387 if ( !error )
00388 error = Load_SBit_Range_Codes( range, stream, 0 );
00389 break;
00390
00391 default:
00392 error = SFNT_Err_Invalid_File_Format;
00393 }
00394
00395 Exit:
00396 return error;
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 FT_LOCAL_DEF( FT_Error )
00417 tt_face_load_eblc( TT_Face face,
00418 FT_Stream stream )
00419 {
00420 FT_Error error = 0;
00421 FT_Memory memory = stream->memory;
00422 FT_Fixed version;
00423 FT_ULong num_strikes;
00424 FT_ULong table_base;
00425
00426 static const FT_Frame_Field sbit_line_metrics_fields[] =
00427 {
00428 #undef FT_STRUCTURE
00429 #define FT_STRUCTURE TT_SBit_LineMetricsRec
00430
00431
00432 FT_FRAME_CHAR( ascender ),
00433 FT_FRAME_CHAR( descender ),
00434 FT_FRAME_BYTE( max_width ),
00435
00436 FT_FRAME_CHAR( caret_slope_numerator ),
00437 FT_FRAME_CHAR( caret_slope_denominator ),
00438 FT_FRAME_CHAR( caret_offset ),
00439
00440 FT_FRAME_CHAR( min_origin_SB ),
00441 FT_FRAME_CHAR( min_advance_SB ),
00442 FT_FRAME_CHAR( max_before_BL ),
00443 FT_FRAME_CHAR( min_after_BL ),
00444 FT_FRAME_CHAR( pads[0] ),
00445 FT_FRAME_CHAR( pads[1] ),
00446 FT_FRAME_END
00447 };
00448
00449 static const FT_Frame_Field strike_start_fields[] =
00450 {
00451 #undef FT_STRUCTURE
00452 #define FT_STRUCTURE TT_SBit_StrikeRec
00453
00454
00455 FT_FRAME_ULONG( ranges_offset ),
00456 FT_FRAME_SKIP_LONG,
00457 FT_FRAME_ULONG( num_ranges ),
00458 FT_FRAME_ULONG( color_ref ),
00459 FT_FRAME_END
00460 };
00461
00462 static const FT_Frame_Field strike_end_fields[] =
00463 {
00464
00465 FT_FRAME_USHORT( start_glyph ),
00466 FT_FRAME_USHORT( end_glyph ),
00467 FT_FRAME_BYTE ( x_ppem ),
00468 FT_FRAME_BYTE ( y_ppem ),
00469 FT_FRAME_BYTE ( bit_depth ),
00470 FT_FRAME_CHAR ( flags ),
00471 FT_FRAME_END
00472 };
00473
00474
00475 face->num_sbit_strikes = 0;
00476
00477
00478 error = face->goto_table( face, TTAG_EBLC, stream, 0 );
00479 if ( error )
00480 error = face->goto_table( face, TTAG_bloc, stream, 0 );
00481 if ( error )
00482 goto Exit;
00483
00484 table_base = FT_STREAM_POS();
00485 if ( FT_FRAME_ENTER( 8L ) )
00486 goto Exit;
00487
00488 version = FT_GET_LONG();
00489 num_strikes = FT_GET_ULONG();
00490
00491 FT_FRAME_EXIT();
00492
00493
00494 if ( version != 0x00020000L ||
00495 num_strikes >= 0x10000L )
00496 {
00497 FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
00498 error = SFNT_Err_Invalid_File_Format;
00499
00500 goto Exit;
00501 }
00502
00503
00504 if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )
00505 goto Exit;
00506
00507 face->num_sbit_strikes = num_strikes;
00508
00509
00510 {
00511 TT_SBit_Strike strike = face->sbit_strikes;
00512 FT_ULong count = num_strikes;
00513
00514
00515 if ( FT_FRAME_ENTER( 48L * num_strikes ) )
00516 goto Exit;
00517
00518 while ( count > 0 )
00519 {
00520 if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike ) ||
00521 FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||
00522 FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||
00523 FT_STREAM_READ_FIELDS( strike_end_fields, strike ) )
00524 break;
00525
00526 count--;
00527 strike++;
00528 }
00529
00530 FT_FRAME_EXIT();
00531 }
00532
00533
00534 {
00535 TT_SBit_Strike strike = face->sbit_strikes;
00536 FT_ULong count = num_strikes;
00537
00538
00539 while ( count > 0 )
00540 {
00541 TT_SBit_Range range;
00542 FT_ULong count2 = strike->num_ranges;
00543
00544
00545
00546 if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||
00547 FT_FRAME_ENTER( strike->num_ranges * 8L ) )
00548 goto Exit;
00549
00550 if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )
00551 goto Exit;
00552
00553 range = strike->sbit_ranges;
00554 while ( count2 > 0 )
00555 {
00556 range->first_glyph = FT_GET_USHORT();
00557 range->last_glyph = FT_GET_USHORT();
00558 range->table_offset = table_base + strike->ranges_offset +
00559 FT_GET_ULONG();
00560 count2--;
00561 range++;
00562 }
00563
00564 FT_FRAME_EXIT();
00565
00566
00567 count2 = strike->num_ranges;
00568 range = strike->sbit_ranges;
00569 while ( count2 > 0 )
00570 {
00571
00572 if ( FT_STREAM_SEEK( range->table_offset ) ||
00573 FT_FRAME_ENTER( 8L ) )
00574 goto Exit;
00575
00576 range->index_format = FT_GET_USHORT();
00577 range->image_format = FT_GET_USHORT();
00578 range->image_offset = FT_GET_ULONG();
00579
00580 FT_FRAME_EXIT();
00581
00582 error = Load_SBit_Range( range, stream );
00583 if ( error )
00584 goto Exit;
00585
00586 count2--;
00587 range++;
00588 }
00589
00590 count--;
00591 strike++;
00592 }
00593 }
00594
00595 Exit:
00596 return error;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 FT_LOCAL_DEF( void )
00612 tt_face_free_eblc( TT_Face face )
00613 {
00614 FT_Memory memory = face->root.memory;
00615 TT_SBit_Strike strike = face->sbit_strikes;
00616 TT_SBit_Strike strike_limit = strike + face->num_sbit_strikes;
00617
00618
00619 if ( strike )
00620 {
00621 for ( ; strike < strike_limit; strike++ )
00622 {
00623 TT_SBit_Range range = strike->sbit_ranges;
00624 TT_SBit_Range range_limit = range + strike->num_ranges;
00625
00626
00627 if ( range )
00628 {
00629 for ( ; range < range_limit; range++ )
00630 {
00631
00632
00633 FT_FREE( range->glyph_offsets );
00634 FT_FREE( range->glyph_codes );
00635 }
00636 }
00637 FT_FREE( strike->sbit_ranges );
00638 strike->num_ranges = 0;
00639 }
00640 FT_FREE( face->sbit_strikes );
00641 }
00642 face->num_sbit_strikes = 0;
00643 }
00644
00645
00646 FT_LOCAL_DEF( FT_Error )
00647 tt_face_set_sbit_strike( TT_Face face,
00648 FT_Size_Request req,
00649 FT_ULong* astrike_index )
00650 {
00651 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
00652 }
00653
00654
00655 FT_LOCAL_DEF( FT_Error )
00656 tt_face_load_strike_metrics( TT_Face face,
00657 FT_ULong strike_index,
00658 FT_Size_Metrics* metrics )
00659 {
00660 TT_SBit_Strike strike;
00661
00662
00663 if ( strike_index >= face->num_sbit_strikes )
00664 return SFNT_Err_Invalid_Argument;
00665
00666 strike = face->sbit_strikes + strike_index;
00667
00668 metrics->x_ppem = strike->x_ppem;
00669 metrics->y_ppem = strike->y_ppem;
00670
00671 metrics->ascender = strike->hori.ascender << 6;
00672 metrics->descender = strike->hori.descender << 6;
00673
00674
00675 metrics->max_advance = ( strike->hori.min_origin_SB +
00676 strike->hori.max_width +
00677 strike->hori.min_advance_SB ) << 6;
00678
00679 metrics->height = metrics->ascender - metrics->descender;
00680
00681 return SFNT_Err_Ok;
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 static FT_Error
00708 find_sbit_range( FT_UInt glyph_index,
00709 TT_SBit_Strike strike,
00710 TT_SBit_Range *arange,
00711 FT_ULong *aglyph_offset )
00712 {
00713 TT_SBit_RangeRec *range, *range_limit;
00714
00715
00716
00717
00718 if ( glyph_index < (FT_UInt)strike->start_glyph ||
00719 glyph_index > (FT_UInt)strike->end_glyph )
00720 goto Fail;
00721
00722
00723 range = strike->sbit_ranges;
00724 range_limit = range + strike->num_ranges;
00725 if ( !range )
00726 goto Fail;
00727
00728 for ( ; range < range_limit; range++ )
00729 {
00730 if ( glyph_index >= (FT_UInt)range->first_glyph &&
00731 glyph_index <= (FT_UInt)range->last_glyph )
00732 {
00733 FT_UShort delta = (FT_UShort)( glyph_index - range->first_glyph );
00734
00735
00736 switch ( range->index_format )
00737 {
00738 case 1:
00739 case 3:
00740 *aglyph_offset = range->glyph_offsets[delta];
00741 break;
00742
00743 case 2:
00744 *aglyph_offset = range->image_offset +
00745 range->image_size * delta;
00746 break;
00747
00748 case 4:
00749 case 5:
00750 {
00751 FT_ULong n;
00752
00753
00754 for ( n = 0; n < range->num_glyphs; n++ )
00755 {
00756 if ( (FT_UInt)range->glyph_codes[n] == glyph_index )
00757 {
00758 if ( range->index_format == 4 )
00759 *aglyph_offset = range->glyph_offsets[n];
00760 else
00761 *aglyph_offset = range->image_offset +
00762 n * range->image_size;
00763 goto Found;
00764 }
00765 }
00766 }
00767
00768
00769 default:
00770 goto Fail;
00771 }
00772
00773 Found:
00774
00775 *arange = range;
00776 return SFNT_Err_Ok;
00777 }
00778 }
00779
00780 Fail:
00781 *arange = 0;
00782 *aglyph_offset = 0;
00783
00784 return SFNT_Err_Invalid_Argument;
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 FT_LOCAL( FT_Error )
00817 tt_find_sbit_image( TT_Face face,
00818 FT_UInt glyph_index,
00819 FT_ULong strike_index,
00820 TT_SBit_Range *arange,
00821 TT_SBit_Strike *astrike,
00822 FT_ULong *aglyph_offset )
00823 {
00824 FT_Error error;
00825 TT_SBit_Strike strike;
00826
00827
00828 if ( !face->sbit_strikes ||
00829 ( face->num_sbit_strikes <= strike_index ) )
00830 goto Fail;
00831
00832 strike = &face->sbit_strikes[strike_index];
00833
00834 error = find_sbit_range( glyph_index, strike,
00835 arange, aglyph_offset );
00836 if ( error )
00837 goto Fail;
00838
00839 *astrike = strike;
00840
00841 return SFNT_Err_Ok;
00842
00843 Fail:
00844
00845 *arange = 0;
00846 *astrike = 0;
00847 *aglyph_offset = 0;
00848
00849 return SFNT_Err_Invalid_Argument;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 FT_LOCAL( FT_Error )
00881 tt_load_sbit_metrics( FT_Stream stream,
00882 TT_SBit_Range range,
00883 TT_SBit_Metrics metrics )
00884 {
00885 FT_Error error = SFNT_Err_Ok;
00886
00887
00888 switch ( range->image_format )
00889 {
00890 case 1:
00891 case 2:
00892 case 8:
00893
00894 {
00895 TT_SBit_SmallMetricsRec smetrics;
00896
00897 static const FT_Frame_Field sbit_small_metrics_fields[] =
00898 {
00899 #undef FT_STRUCTURE
00900 #define FT_STRUCTURE TT_SBit_SmallMetricsRec
00901
00902 FT_FRAME_START( 5 ),
00903 FT_FRAME_BYTE( height ),
00904 FT_FRAME_BYTE( width ),
00905 FT_FRAME_CHAR( bearingX ),
00906 FT_FRAME_CHAR( bearingY ),
00907 FT_FRAME_BYTE( advance ),
00908 FT_FRAME_END
00909 };
00910
00911
00912
00913 if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) )
00914 goto Exit;
00915
00916
00917 metrics->height = smetrics.height;
00918 metrics->width = smetrics.width;
00919 metrics->horiBearingX = smetrics.bearingX;
00920 metrics->horiBearingY = smetrics.bearingY;
00921 metrics->horiAdvance = smetrics.advance;
00922
00923
00924
00925 metrics->vertBearingX = 0;
00926 metrics->vertBearingY = 0;
00927 metrics->vertAdvance = 0;
00928 }
00929 break;
00930
00931 case 6:
00932 case 7:
00933 case 9:
00934
00935 if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) )
00936 goto Exit;
00937 break;
00938
00939 case 5:
00940 default:
00941 if ( range->index_format == 2 || range->index_format == 5 )
00942 *metrics = range->metrics;
00943 else
00944 return SFNT_Err_Invalid_File_Format;
00945 }
00946
00947 Exit:
00948 return error;
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 static void
00967 crop_bitmap( FT_Bitmap* map,
00968 TT_SBit_Metrics metrics )
00969 {
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 FT_Int rows, count;
00988 FT_Long line_len;
00989 FT_Byte* line;
00990
00991
00992
00993
00994
00995
00996
00997 {
00998 line = (FT_Byte*)map->buffer;
00999 rows = map->rows;
01000 line_len = map->pitch;
01001
01002
01003 for ( count = 0; count < rows; count++ )
01004 {
01005 FT_Byte* cur = line;
01006 FT_Byte* limit = line + line_len;
01007
01008
01009 for ( ; cur < limit; cur++ )
01010 if ( cur[0] )
01011 goto Found_Top;
01012
01013
01014 line = limit;
01015 }
01016
01017 Found_Top:
01018
01019 if ( count >= rows )
01020 goto Empty_Bitmap;
01021
01022
01023 if ( count > 0 )
01024 {
01025 line = (FT_Byte*)map->buffer;
01026
01027 FT_MEM_MOVE( line, line + count * line_len,
01028 ( rows - count ) * line_len );
01029
01030 metrics->height = (FT_Byte)( metrics->height - count );
01031 metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );
01032 metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );
01033
01034 map->rows -= count;
01035 rows -= count;
01036 }
01037 }
01038
01039
01040
01041
01042
01043 {
01044 line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;
01045
01046 for ( count = 0; count < rows; count++ )
01047 {
01048 FT_Byte* cur = line;
01049 FT_Byte* limit = line + line_len;
01050
01051
01052 for ( ; cur < limit; cur++ )
01053 if ( cur[0] )
01054 goto Found_Bottom;
01055
01056
01057 line -= line_len;
01058 }
01059
01060 Found_Bottom:
01061 if ( count > 0 )
01062 {
01063 metrics->height = (FT_Byte)( metrics->height - count );
01064 rows -= count;
01065 map->rows -= count;
01066 }
01067 }
01068
01069
01070
01071
01072
01073 do
01074 {
01075 FT_Byte* limit;
01076
01077
01078 line = (FT_Byte*)map->buffer;
01079 limit = line + rows * line_len;
01080
01081 for ( ; line < limit; line += line_len )
01082 if ( line[0] & 0x80 )
01083 goto Found_Left;
01084
01085
01086 line = (FT_Byte*)map->buffer;
01087 limit = line + rows * line_len;
01088
01089 for ( ; line < limit; line += line_len )
01090 {
01091 FT_Int n, width = map->width;
01092 FT_Byte old;
01093 FT_Byte* cur = line;
01094
01095
01096 old = (FT_Byte)(cur[0] << 1);
01097 for ( n = 8; n < width; n += 8 )
01098 {
01099 FT_Byte val;
01100
01101
01102 val = cur[1];
01103 cur[0] = (FT_Byte)( old | ( val >> 7 ) );
01104 old = (FT_Byte)( val << 1 );
01105 cur++;
01106 }
01107 cur[0] = old;
01108 }
01109
01110 map->width--;
01111 metrics->horiBearingX++;
01112 metrics->vertBearingX++;
01113 metrics->width--;
01114
01115 } while ( map->width > 0 );
01116
01117 Found_Left:
01118
01119
01120
01121
01122
01123
01124 do
01125 {
01126 FT_Int right = map->width - 1;
01127 FT_Byte* limit;
01128 FT_Byte mask;
01129
01130
01131 line = (FT_Byte*)map->buffer + ( right >> 3 );
01132 limit = line + rows * line_len;
01133 mask = (FT_Byte)( 0x80 >> ( right & 7 ) );
01134
01135 for ( ; line < limit; line += line_len )
01136 if ( line[0] & mask )
01137 goto Found_Right;
01138
01139
01140 map->width--;
01141 metrics->width--;
01142
01143 } while ( map->width > 0 );
01144
01145 Found_Right:
01146
01147 return;
01148
01149 Empty_Bitmap:
01150 map->width = 0;
01151 map->rows = 0;
01152 map->pitch = 0;
01153 map->pixel_mode = FT_PIXEL_MODE_MONO;
01154 }
01155
01156
01157 static FT_Error
01158 Load_SBit_Single( FT_Bitmap* map,
01159 FT_Int x_offset,
01160 FT_Int y_offset,
01161 FT_Int pix_bits,
01162 FT_UShort image_format,
01163 TT_SBit_Metrics metrics,
01164 FT_Stream stream )
01165 {
01166 FT_Error error;
01167
01168
01169
01170 if ( x_offset < 0 || x_offset + metrics->width > map->width ||
01171 y_offset < 0 || y_offset + metrics->height > map->rows )
01172 {
01173 error = SFNT_Err_Invalid_Argument;
01174
01175 goto Exit;
01176 }
01177
01178 {
01179 FT_Int glyph_width = metrics->width;
01180 FT_Int glyph_height = metrics->height;
01181 FT_Int glyph_size;
01182 FT_Int line_bits = pix_bits * glyph_width;
01183 FT_Bool pad_bytes = 0;
01184
01185
01186
01187 switch ( image_format )
01188 {
01189 case 1:
01190 case 6:
01191 {
01192 FT_Int line_length;
01193
01194
01195 switch ( pix_bits )
01196 {
01197 case 1:
01198 line_length = ( glyph_width + 7 ) >> 3;
01199 break;
01200 case 2:
01201 line_length = ( glyph_width + 3 ) >> 2;
01202 break;
01203 case 4:
01204 line_length = ( glyph_width + 1 ) >> 1;
01205 break;
01206 default:
01207 line_length = glyph_width;
01208 }
01209
01210 glyph_size = glyph_height * line_length;
01211 pad_bytes = 1;
01212 }
01213 break;
01214
01215 case 2:
01216 case 5:
01217 case 7:
01218 line_bits = glyph_width * pix_bits;
01219 glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
01220 break;
01221
01222 default:
01223 return SFNT_Err_Invalid_File_Format;
01224 }
01225
01226
01227 if ( FT_FRAME_ENTER( glyph_size ) )
01228 goto Exit;
01229
01230
01231
01232
01233 blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
01234 x_offset * pix_bits, y_offset, metrics->height );
01235
01236 FT_FRAME_EXIT();
01237 }
01238
01239 Exit:
01240 return error;
01241 }
01242
01243
01244 static FT_Error
01245 Load_SBit_Image( TT_SBit_Strike strike,
01246 TT_SBit_Range range,
01247 FT_ULong ebdt_pos,
01248 FT_ULong glyph_offset,
01249 FT_GlyphSlot slot,
01250 FT_Int x_offset,
01251 FT_Int y_offset,
01252 FT_Stream stream,
01253 TT_SBit_Metrics metrics,
01254 FT_Int depth )
01255 {
01256 FT_Memory memory = stream->memory;
01257 FT_Bitmap* map = &slot->bitmap;
01258 FT_Error error;
01259
01260
01261
01262 if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
01263 goto Exit;
01264
01265 error = tt_load_sbit_metrics( stream, range, metrics );
01266 if ( error )
01267 goto Exit;
01268
01269
01270
01271
01272 if ( depth == 0 )
01273 {
01274 FT_Long size;
01275
01276
01277 map->width = metrics->width;
01278 map->rows = metrics->height;
01279
01280 switch ( strike->bit_depth )
01281 {
01282 case 1:
01283 map->pixel_mode = FT_PIXEL_MODE_MONO;
01284 map->pitch = ( map->width + 7 ) >> 3;
01285 break;
01286
01287 case 2:
01288 map->pixel_mode = FT_PIXEL_MODE_GRAY2;
01289 map->pitch = ( map->width + 3 ) >> 2;
01290 break;
01291
01292 case 4:
01293 map->pixel_mode = FT_PIXEL_MODE_GRAY4;
01294 map->pitch = ( map->width + 1 ) >> 1;
01295 break;
01296
01297 case 8:
01298 map->pixel_mode = FT_PIXEL_MODE_GRAY;
01299 map->pitch = map->width;
01300 break;
01301
01302 default:
01303 return SFNT_Err_Invalid_File_Format;
01304 }
01305
01306 size = map->rows * map->pitch;
01307
01308
01309 if ( size == 0 )
01310 goto Exit;
01311
01312 error = ft_glyphslot_alloc_bitmap( slot, size );
01313 if (error)
01314 goto Exit;
01315 }
01316
01317 switch ( range->image_format )
01318 {
01319 case 1:
01320 case 2:
01321 case 5:
01322 case 6:
01323 case 7:
01324 return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
01325 range->image_format, metrics, stream );
01326
01327 case 8:
01328 if ( FT_STREAM_SKIP( 1L ) )
01329 {
01330 error = SFNT_Err_Invalid_Stream_Skip;
01331 goto Exit;
01332 }
01333
01334
01335 case 9:
01336 break;
01337
01338 default:
01339 return SFNT_Err_Invalid_File_Format;
01340 }
01341
01342
01343
01344 {
01345 TT_SBit_Component components;
01346 TT_SBit_Component comp;
01347 FT_UShort num_components, count;
01348
01349
01350 if ( FT_READ_USHORT( num_components ) ||
01351 FT_NEW_ARRAY( components, num_components ) )
01352 goto Exit;
01353
01354 count = num_components;
01355
01356 if ( FT_FRAME_ENTER( 4L * num_components ) )
01357 goto Fail_Memory;
01358
01359 for ( comp = components; count > 0; count--, comp++ )
01360 {
01361 comp->glyph_code = FT_GET_USHORT();
01362 comp->x_offset = FT_GET_CHAR();
01363 comp->y_offset = FT_GET_CHAR();
01364 }
01365
01366 FT_FRAME_EXIT();
01367
01368
01369 count = num_components;
01370 comp = components;
01371 for ( ; count > 0; count--, comp++ )
01372 {
01373 TT_SBit_Range elem_range;
01374 TT_SBit_MetricsRec elem_metrics;
01375 FT_ULong elem_offset;
01376
01377
01378
01379 error = find_sbit_range( comp->glyph_code,
01380 strike,
01381 &elem_range,
01382 &elem_offset );
01383 if ( error )
01384 goto Fail_Memory;
01385
01386
01387 error = Load_SBit_Image( strike,
01388 elem_range,
01389 ebdt_pos,
01390 elem_offset,
01391 slot,
01392 x_offset + comp->x_offset,
01393 y_offset + comp->y_offset,
01394 stream,
01395 &elem_metrics,
01396 depth + 1 );
01397 if ( error )
01398 goto Fail_Memory;
01399 }
01400
01401 Fail_Memory:
01402 FT_FREE( components );
01403 }
01404
01405 Exit:
01406 return error;
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443 FT_LOCAL_DEF( FT_Error )
01444 tt_face_load_sbit_image( TT_Face face,
01445 FT_ULong strike_index,
01446 FT_UInt glyph_index,
01447 FT_UInt load_flags,
01448 FT_Stream stream,
01449 FT_Bitmap *map,
01450 TT_SBit_MetricsRec *metrics )
01451 {
01452 FT_Error error;
01453 FT_ULong ebdt_pos, glyph_offset;
01454
01455 TT_SBit_Strike strike;
01456 TT_SBit_Range range;
01457
01458
01459
01460 error = tt_find_sbit_image( face, glyph_index, strike_index,
01461 &range, &strike, &glyph_offset );
01462 if ( error )
01463 goto Exit;
01464
01465
01466
01467 error = face->goto_table( face, TTAG_EBDT, stream, 0 );
01468 if ( error )
01469 error = face->goto_table( face, TTAG_bdat, stream, 0 );
01470 if ( error )
01471 goto Exit;
01472
01473 ebdt_pos = FT_STREAM_POS();
01474
01475 error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
01476 face->root.glyph, 0, 0, stream, metrics, 0 );
01477 if ( error )
01478 goto Exit;
01479
01480
01481 if ( strike->flags & 1 )
01482 {
01483
01484 FT_Int advance;
01485
01486
01487 advance = strike->hori.ascender - strike->hori.descender;
01488
01489
01490
01491 metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
01492 metrics->vertBearingY = (FT_Char)( ( advance - metrics->height ) / 2 );
01493 metrics->vertAdvance = (FT_Char)( advance * 12 / 10 );
01494 }
01495
01496
01497 if ( load_flags & FT_LOAD_CROP_BITMAP )
01498 crop_bitmap( map, metrics );
01499
01500 Exit:
01501 return error;
01502 }
01503
01504 #endif
01505
01506
01507