ReactOS 0.4.16-dev-981-g80eb313
ftbitmap.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * ftbitmap.c
4 *
5 * FreeType utility functions for bitmaps (body).
6 *
7 * Copyright (C) 2004-2019 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
15 *
16 */
17
18
19#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21
22#include FT_BITMAP_H
23#include FT_IMAGE_H
24#include FT_INTERNAL_OBJECTS_H
25
26
27 /**************************************************************************
28 *
29 * The macro FT_COMPONENT is used in trace mode. It is an implicit
30 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
31 * messages during execution.
32 */
33#undef FT_COMPONENT
34#define FT_COMPONENT bitmap
35
36
37 static
38 const FT_Bitmap null_bitmap = { 0, 0, 0, NULL, 0, 0, 0, NULL };
39
40
41 /* documentation is in ftbitmap.h */
42
43 FT_EXPORT_DEF( void )
45 {
46 if ( abitmap )
47 *abitmap = null_bitmap;
48 }
49
50
51 /* deprecated function name; retained for ABI compatibility */
52
53 FT_EXPORT_DEF( void )
55 {
56 if ( abitmap )
57 *abitmap = null_bitmap;
58 }
59
60
61 /* documentation is in ftbitmap.h */
62
67 {
70
71 FT_Int pitch;
73
74 FT_Int source_pitch_sign, target_pitch_sign;
75
76
77 if ( !library )
78 return FT_THROW( Invalid_Library_Handle );
79
80 if ( !source || !target )
81 return FT_THROW( Invalid_Argument );
82
83 if ( source == target )
84 return FT_Err_Ok;
85
86 source_pitch_sign = source->pitch < 0 ? -1 : 1;
87 target_pitch_sign = target->pitch < 0 ? -1 : 1;
88
89 if ( !source->buffer )
90 {
91 *target = *source;
92 if ( source_pitch_sign != target_pitch_sign )
93 target->pitch = -target->pitch;
94
95 return FT_Err_Ok;
96 }
97
99 pitch = source->pitch;
100
101 if ( pitch < 0 )
102 pitch = -pitch;
103 size = (FT_ULong)pitch * source->rows;
104
105 if ( target->buffer )
106 {
107 FT_Int target_pitch = target->pitch;
108 FT_ULong target_size;
109
110
111 if ( target_pitch < 0 )
112 target_pitch = -target_pitch;
113 target_size = (FT_ULong)target_pitch * target->rows;
114
115 if ( target_size != size )
116 (void)FT_QREALLOC( target->buffer, target_size, size );
117 }
118 else
119 (void)FT_QALLOC( target->buffer, size );
120
121 if ( !error )
122 {
123 unsigned char *p;
124
125
126 p = target->buffer;
127 *target = *source;
128 target->buffer = p;
129
130 if ( source_pitch_sign == target_pitch_sign )
131 FT_MEM_COPY( target->buffer, source->buffer, size );
132 else
133 {
134 /* take care of bitmap flow */
135 FT_UInt i;
136 FT_Byte* s = source->buffer;
137 FT_Byte* t = target->buffer;
138
139
140 t += (FT_ULong)pitch * ( target->rows - 1 );
141
142 for ( i = target->rows; i > 0; i-- )
143 {
144 FT_ARRAY_COPY( t, s, pitch );
145
146 s += pitch;
147 t -= pitch;
148 }
149 }
150 }
151
152 return error;
153 }
154
155
156 /* Enlarge `bitmap' horizontally and vertically by `xpixels' */
157 /* and `ypixels', respectively. */
158
159 static FT_Error
162 FT_UInt xpixels,
163 FT_UInt ypixels )
164 {
166 unsigned int pitch;
167 unsigned int new_pitch;
168 FT_UInt bpp;
170 unsigned char* buffer = NULL;
171
172
173 width = bitmap->width;
174 height = bitmap->rows;
175 pitch = (unsigned int)FT_ABS( bitmap->pitch );
176
177 switch ( bitmap->pixel_mode )
178 {
180 bpp = 1;
181 new_pitch = ( width + xpixels + 7 ) >> 3;
182 break;
184 bpp = 2;
185 new_pitch = ( width + xpixels + 3 ) >> 2;
186 break;
188 bpp = 4;
189 new_pitch = ( width + xpixels + 1 ) >> 1;
190 break;
194 bpp = 8;
195 new_pitch = width + xpixels;
196 break;
197 default:
198 return FT_THROW( Invalid_Glyph_Format );
199 }
200
201 /* if no need to allocate memory */
202 if ( ypixels == 0 && new_pitch <= pitch )
203 {
204 /* zero the padding */
205 FT_UInt bit_width = pitch * 8;
206 FT_UInt bit_last = ( width + xpixels ) * bpp;
207
208
209 if ( bit_last < bit_width )
210 {
211 FT_Byte* line = bitmap->buffer + ( bit_last >> 3 );
212 FT_Byte* end = bitmap->buffer + pitch;
213 FT_UInt shift = bit_last & 7;
214 FT_UInt mask = 0xFF00U >> shift;
216
217
218 for ( ; count > 0; count--, line += pitch, end += pitch )
219 {
220 FT_Byte* write = line;
221
222
223 if ( shift > 0 )
224 {
225 write[0] = (FT_Byte)( write[0] & mask );
226 write++;
227 }
228 if ( write < end )
230 }
231 }
232
233 return FT_Err_Ok;
234 }
235
236 /* otherwise allocate new buffer */
237 if ( FT_QALLOC_MULT( buffer, bitmap->rows + ypixels, new_pitch ) )
238 return error;
239
240 /* new rows get added at the top of the bitmap, */
241 /* thus take care of the flow direction */
242 if ( bitmap->pitch > 0 )
243 {
244 FT_UInt len = ( width * bpp + 7 ) >> 3;
245
246 unsigned char* in = bitmap->buffer;
247 unsigned char* out = buffer;
248
249 unsigned char* limit = bitmap->buffer + pitch * bitmap->rows;
250 unsigned int delta = new_pitch - len;
251
252
253 FT_MEM_ZERO( out, new_pitch * ypixels );
254 out += new_pitch * ypixels;
255
256 while ( in < limit )
257 {
258 FT_MEM_COPY( out, in, len );
259 in += pitch;
260 out += len;
261
262 /* we use FT_QALLOC_MULT, which doesn't zero out the buffer; */
263 /* consequently, we have to manually zero out the remaining bytes */
264 FT_MEM_ZERO( out, delta );
265 out += delta;
266 }
267 }
268 else
269 {
270 FT_UInt len = ( width * bpp + 7 ) >> 3;
271
272 unsigned char* in = bitmap->buffer;
273 unsigned char* out = buffer;
274
275 unsigned char* limit = bitmap->buffer + pitch * bitmap->rows;
276 unsigned int delta = new_pitch - len;
277
278
279 while ( in < limit )
280 {
281 FT_MEM_COPY( out, in, len );
282 in += pitch;
283 out += len;
284
285 FT_MEM_ZERO( out, delta );
286 out += delta;
287 }
288
289 FT_MEM_ZERO( out, new_pitch * ypixels );
290 }
291
292 FT_FREE( bitmap->buffer );
293 bitmap->buffer = buffer;
294
295 /* set pitch only, width and height are left untouched */
296 if ( bitmap->pitch < 0 )
297 bitmap->pitch = -(int)new_pitch;
298 else
299 bitmap->pitch = (int)new_pitch;
300
301 return FT_Err_Ok;
302 }
303
304
305 /* documentation is in ftbitmap.h */
306
310 FT_Pos xStrength,
311 FT_Pos yStrength )
312 {
314 unsigned char* p;
315 FT_Int i, x, pitch;
316 FT_UInt y;
317 FT_Int xstr, ystr;
318
319
320 if ( !library )
321 return FT_THROW( Invalid_Library_Handle );
322
323 if ( !bitmap || !bitmap->buffer )
324 return FT_THROW( Invalid_Argument );
325
326 if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
327 ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
328 return FT_THROW( Invalid_Argument );
329
330 xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
331 ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
332
333 if ( xstr == 0 && ystr == 0 )
334 return FT_Err_Ok;
335 else if ( xstr < 0 || ystr < 0 )
336 return FT_THROW( Invalid_Argument );
337
338 switch ( bitmap->pixel_mode )
339 {
342 {
343 FT_Bitmap tmp;
344
345
346 /* convert to 8bpp */
347 FT_Bitmap_Init( &tmp );
348 error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 );
349 if ( error )
350 return error;
351
353 *bitmap = tmp;
354 }
355 break;
356
358 if ( xstr > 8 )
359 xstr = 8;
360 break;
361
363 xstr *= 3;
364 break;
365
367 ystr *= 3;
368 break;
369
371 /* We don't embolden color glyphs. */
372 return FT_Err_Ok;
373 }
374
376 (FT_UInt)xstr, (FT_UInt)ystr );
377 if ( error )
378 return error;
379
380 /* take care of bitmap flow */
381 pitch = bitmap->pitch;
382 if ( pitch > 0 )
383 p = bitmap->buffer + pitch * ystr;
384 else
385 {
386 pitch = -pitch;
387 p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 );
388 }
389
390 /* for each row */
391 for ( y = 0; y < bitmap->rows; y++ )
392 {
393 /*
394 * Horizontally:
395 *
396 * From the last pixel on, make each pixel or'ed with the
397 * `xstr' pixels before it.
398 */
399 for ( x = pitch - 1; x >= 0; x-- )
400 {
401 unsigned char tmp;
402
403
404 tmp = p[x];
405 for ( i = 1; i <= xstr; i++ )
406 {
407 if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
408 {
409 p[x] |= tmp >> i;
410
411 /* the maximum value of 8 for `xstr' comes from here */
412 if ( x > 0 )
413 p[x] |= p[x - 1] << ( 8 - i );
414
415#if 0
416 if ( p[x] == 0xFF )
417 break;
418#endif
419 }
420 else
421 {
422 if ( x - i >= 0 )
423 {
424 if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
425 {
426 p[x] = (unsigned char)( bitmap->num_grays - 1 );
427 break;
428 }
429 else
430 {
431 p[x] = (unsigned char)( p[x] + p[x - i] );
432 if ( p[x] == bitmap->num_grays - 1 )
433 break;
434 }
435 }
436 else
437 break;
438 }
439 }
440 }
441
442 /*
443 * Vertically:
444 *
445 * Make the above `ystr' rows or'ed with it.
446 */
447 for ( x = 1; x <= ystr; x++ )
448 {
449 unsigned char* q;
450
451
452 q = p - bitmap->pitch * x;
453 for ( i = 0; i < pitch; i++ )
454 q[i] |= p[i];
455 }
456
457 p += bitmap->pitch;
458 }
459
460 bitmap->width += (FT_UInt)xstr;
461 bitmap->rows += (FT_UInt)ystr;
462
463 return FT_Err_Ok;
464 }
465
466
467 static FT_Byte
469 {
470 FT_UInt a = bgra[3];
471 FT_UInt l;
472
473
474 /* Short-circuit transparent color to avoid division by zero. */
475 if ( !a )
476 return 0;
477
478 /*
479 * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722
480 * coefficients for RGB channels *on the linear colors*.
481 * A gamma of 2.2 is fair to assume. And then, we need to
482 * undo the premultiplication too.
483 *
484 * https://accessibility.kde.org/hsl-adjusted.php
485 *
486 * We do the computation with integers only, applying a gamma of 2.0.
487 * We guarantee 32-bit arithmetic to avoid overflow but the resulting
488 * luminosity fits into 16 bits.
489 *
490 */
491
492 l = ( 4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] +
493 46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] +
494 13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16;
495
496 /*
497 * Final transparency can be determined as follows.
498 *
499 * - If alpha is zero, we want 0.
500 * - If alpha is zero and luminosity is zero, we want 255.
501 * - If alpha is zero and luminosity is one, we want 0.
502 *
503 * So the formula is a * (1 - l) = a - l * a.
504 *
505 * We still need to undo premultiplication by dividing l by a*a.
506 *
507 */
508
509 return (FT_Byte)( a - l / a );
510 }
511
512
513 /* documentation is in ftbitmap.h */
514
515#ifdef __REACTOS__
517 FT_Bitmap_Convert_ReactOS_Hack( FT_Library library,
518 const FT_Bitmap *source,
521 FT_Bool hack )
522#else
528#endif
529 {
532
533 FT_Byte* s;
534 FT_Byte* t;
535
536
537 if ( !library )
538 return FT_THROW( Invalid_Library_Handle );
539
540 if ( !source || !target )
541 return FT_THROW( Invalid_Argument );
542
544
545 switch ( source->pixel_mode )
546 {
554 {
555 FT_Int pad, old_target_pitch, target_pitch;
557
558
559 old_target_pitch = target->pitch;
560 if ( old_target_pitch < 0 )
561 old_target_pitch = -old_target_pitch;
562
563 old_size = target->rows * (FT_UInt)old_target_pitch;
564
565 target->pixel_mode = FT_PIXEL_MODE_GRAY;
566 target->rows = source->rows;
567 target->width = source->width;
568
569 pad = 0;
570 if ( alignment > 0 )
571 {
572 pad = (FT_Int)source->width % alignment;
573 if ( pad != 0 )
574 pad = alignment - pad;
575 }
576
577 target_pitch = (FT_Int)source->width + pad;
578
579 if ( target_pitch > 0 &&
580 (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
581 return FT_THROW( Invalid_Argument );
582
583 if ( FT_QREALLOC( target->buffer,
584 old_size, target->rows * (FT_UInt)target_pitch ) )
585 return error;
586
587 target->pitch = target->pitch < 0 ? -target_pitch : target_pitch;
588 }
589 break;
590
591 default:
592 error = FT_THROW( Invalid_Argument );
593 }
594
595 s = source->buffer;
596 t = target->buffer;
597
598 /* take care of bitmap flow */
599 if ( source->pitch < 0 )
600 s -= source->pitch * (FT_Int)( source->rows - 1 );
601 if ( target->pitch < 0 )
602 t -= target->pitch * (FT_Int)( target->rows - 1 );
603
604 switch ( source->pixel_mode )
605 {
607 {
608 FT_UInt i;
609
610
611 target->num_grays = 2;
612
613 for ( i = source->rows; i > 0; i-- )
614 {
615 FT_Byte* ss = s;
616 FT_Byte* tt = t;
617 FT_UInt j;
618
619
620 /* get the full bytes */
621 for ( j = source->width >> 3; j > 0; j-- )
622 {
623 FT_Int val = ss[0]; /* avoid a byte->int cast on each line */
624
625#ifdef __REACTOS__
626 if (hack)
627 {
628 tt[0] = (FT_Byte)( ( val & 0x80 ) ? 0xff : 0);
629 tt[1] = (FT_Byte)( ( val & 0x40 ) ? 0xff : 0);
630 tt[2] = (FT_Byte)( ( val & 0x20 ) ? 0xff : 0);
631 tt[3] = (FT_Byte)( ( val & 0x10 ) ? 0xff : 0);
632 tt[4] = (FT_Byte)( ( val & 0x08 ) ? 0xff : 0);
633 tt[5] = (FT_Byte)( ( val & 0x04 ) ? 0xff : 0);
634 tt[6] = (FT_Byte)( ( val & 0x02 ) ? 0xff : 0);
635 tt[7] = (FT_Byte)( ( val & 0x01 ) ? 0xff : 0);
636 }
637 else
638 {
639#endif
640 tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 );
641 tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 );
642 tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 );
643 tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 );
644 tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 );
645 tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 );
646 tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 );
647 tt[7] = (FT_Byte)( val & 0x01 );
648#ifdef __REACTOS__
649 }
650#endif
651
652 tt += 8;
653 ss += 1;
654 }
655
656 /* get remaining pixels (if any) */
657 j = source->width & 7;
658 if ( j > 0 )
659 {
660 FT_Int val = *ss;
661
662
663 for ( ; j > 0; j-- )
664 {
665#ifdef __REACTOS__
666 if (hack)
667 tt[0] = (FT_Byte)( ( val & 0x80 ) ? 0xff : 0);
668 else
669#endif
670 tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7);
671 val <<= 1;
672 tt += 1;
673 }
674 }
675
676 s += source->pitch;
677 t += target->pitch;
678 }
679 }
680 break;
681
682
686 {
687 FT_UInt width = source->width;
688 FT_UInt i;
689
690
691 target->num_grays = 256;
692
693 for ( i = source->rows; i > 0; i-- )
694 {
695 FT_ARRAY_COPY( t, s, width );
696
697 s += source->pitch;
698 t += target->pitch;
699 }
700 }
701 break;
702
703
705 {
706 FT_UInt i;
707
708
709 target->num_grays = 4;
710
711 for ( i = source->rows; i > 0; i-- )
712 {
713 FT_Byte* ss = s;
714 FT_Byte* tt = t;
715 FT_UInt j;
716
717
718 /* get the full bytes */
719 for ( j = source->width >> 2; j > 0; j-- )
720 {
721 FT_Int val = ss[0];
722
723
724 tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
725 tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 );
726 tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 );
727 tt[3] = (FT_Byte)( ( val & 0x03 ) );
728
729 ss += 1;
730 tt += 4;
731 }
732
733 j = source->width & 3;
734 if ( j > 0 )
735 {
736 FT_Int val = ss[0];
737
738
739 for ( ; j > 0; j-- )
740 {
741 tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 );
742 val <<= 2;
743 tt += 1;
744 }
745 }
746
747 s += source->pitch;
748 t += target->pitch;
749 }
750 }
751 break;
752
753
755 {
756 FT_UInt i;
757
758
759 target->num_grays = 16;
760
761 for ( i = source->rows; i > 0; i-- )
762 {
763 FT_Byte* ss = s;
764 FT_Byte* tt = t;
765 FT_UInt j;
766
767
768 /* get the full bytes */
769 for ( j = source->width >> 1; j > 0; j-- )
770 {
771 FT_Int val = ss[0];
772
773
774 tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 );
775 tt[1] = (FT_Byte)( ( val & 0x0F ) );
776
777 ss += 1;
778 tt += 2;
779 }
780
781 if ( source->width & 1 )
782 tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 );
783
784 s += source->pitch;
785 t += target->pitch;
786 }
787 }
788 break;
789
790
792 {
793 FT_UInt i;
794
795
796 target->num_grays = 256;
797
798 for ( i = source->rows; i > 0; i-- )
799 {
800 FT_Byte* ss = s;
801 FT_Byte* tt = t;
802 FT_UInt j;
803
804
805 for ( j = source->width; j > 0; j-- )
806 {
808
809 ss += 4;
810 tt += 1;
811 }
812
813 s += source->pitch;
814 t += target->pitch;
815 }
816 }
817 break;
818
819 default:
820 ;
821 }
822
823 return error;
824 }
825
826#ifdef __REACTOS__
829 const FT_Bitmap *source,
832 {
833 return FT_Bitmap_Convert_ReactOS_Hack(library, source, target, alignment, FALSE);
834 }
835#endif
836
837 /* documentation is in ftbitmap.h */
838
841 const FT_Bitmap* source_,
842 const FT_Vector source_offset_,
844 FT_Vector *atarget_offset,
846 {
849
850 FT_Bitmap source_bitmap;
851 const FT_Bitmap* source;
852
853 FT_Vector source_offset;
854 FT_Vector target_offset;
855
856 FT_Bool free_source_bitmap = 0;
857 FT_Bool free_target_bitmap_on_error = 0;
858
859 FT_Pos source_llx, source_lly, source_urx, source_ury;
860 FT_Pos target_llx, target_lly, target_urx, target_ury;
861 FT_Pos final_llx, final_lly, final_urx, final_ury;
862
863 unsigned int final_rows, final_width;
864 long x, y;
865
866
867 if ( !library || !target || !source_ || !atarget_offset )
868 return FT_THROW( Invalid_Argument );
869
871
872 if ( !( target->pixel_mode == FT_PIXEL_MODE_NONE ||
873 ( target->pixel_mode == FT_PIXEL_MODE_BGRA &&
874 target->buffer ) ) )
875 return FT_THROW( Invalid_Argument );
876
877 if ( source_->pixel_mode == FT_PIXEL_MODE_NONE )
878 return FT_Err_Ok; /* nothing to do */
879
880 /* pitches must have the same sign */
881 if ( target->pixel_mode == FT_PIXEL_MODE_BGRA &&
882 ( source_->pitch ^ target->pitch ) < 0 )
883 return FT_THROW( Invalid_Argument );
884
885 if ( !( source_->width && source_->rows ) )
886 return FT_Err_Ok; /* nothing to do */
887
888 /* assure integer pixel offsets */
889 source_offset.x = FT_PIX_FLOOR( source_offset_.x );
890 source_offset.y = FT_PIX_FLOOR( source_offset_.y );
891 target_offset.x = FT_PIX_FLOOR( atarget_offset->x );
892 target_offset.y = FT_PIX_FLOOR( atarget_offset->y );
893
894 /* get source bitmap dimensions */
895 source_llx = source_offset.x;
896 if ( FT_LONG_MIN + (FT_Pos)( source_->rows << 6 ) + 64 > source_offset.y )
897 {
898 FT_TRACE5((
899 "FT_Bitmap_Blend: y coordinate overflow in source bitmap\n" ));
900 return FT_THROW( Invalid_Argument );
901 }
902 source_lly = source_offset.y - ( source_->rows << 6 );
903
904 if ( FT_LONG_MAX - (FT_Pos)( source_->width << 6 ) - 64 < source_llx )
905 {
906 FT_TRACE5((
907 "FT_Bitmap_Blend: x coordinate overflow in source bitmap\n" ));
908 return FT_THROW( Invalid_Argument );
909 }
910 source_urx = source_llx + ( source_->width << 6 );
911 source_ury = source_offset.y;
912
913 /* get target bitmap dimensions */
914 if ( target->width && target->rows )
915 {
916 target_llx = target_offset.x;
917 if ( FT_LONG_MIN + (FT_Pos)( target->rows << 6 ) > target_offset.y )
918 {
919 FT_TRACE5((
920 "FT_Bitmap_Blend: y coordinate overflow in target bitmap\n" ));
921 return FT_THROW( Invalid_Argument );
922 }
923 target_lly = target_offset.y - ( target->rows << 6 );
924
925 if ( FT_LONG_MAX - (FT_Pos)( target->width << 6 ) < target_llx )
926 {
927 FT_TRACE5((
928 "FT_Bitmap_Blend: x coordinate overflow in target bitmap\n" ));
929 return FT_THROW( Invalid_Argument );
930 }
931 target_urx = target_llx + ( target->width << 6 );
932 target_ury = target_offset.y;
933 }
934 else
935 {
936 target_llx = FT_LONG_MAX;
937 target_lly = FT_LONG_MAX;
938 target_urx = FT_LONG_MIN;
939 target_ury = FT_LONG_MIN;
940 }
941
942 /* compute final bitmap dimensions */
943 final_llx = FT_MIN( source_llx, target_llx );
944 final_lly = FT_MIN( source_lly, target_lly );
945 final_urx = FT_MAX( source_urx, target_urx );
946 final_ury = FT_MAX( source_ury, target_ury );
947
948 final_width = ( final_urx - final_llx ) >> 6;
949 final_rows = ( final_ury - final_lly ) >> 6;
950
951#ifdef FT_DEBUG_LEVEL_TRACE
952 FT_TRACE5(( "FT_Bitmap_Blend:\n"
953 " source bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
954 source_llx / 64, source_lly / 64,
955 source_urx / 64, source_ury / 64,
956 source_->width, source_->rows ));
957
958 if ( target->width && target->rows )
959 FT_TRACE5(( " target bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
960 target_llx / 64, target_lly / 64,
961 target_urx / 64, target_ury / 64,
962 target->width, target->rows ));
963 else
964 FT_TRACE5(( " target bitmap: empty\n" ));
965
966 FT_TRACE5(( " final bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
967 final_llx / 64, final_lly / 64,
968 final_urx / 64, final_ury / 64,
969 final_width, final_rows ));
970#endif /* FT_DEBUG_LEVEL_TRACE */
971
972 /* for blending, set offset vector of final bitmap */
973 /* temporarily to (0,0) */
974 source_llx -= final_llx;
975 source_lly -= final_lly;
976
977 if ( target->width && target->rows )
978 {
979 target_llx -= final_llx;
980 target_lly -= final_lly;
981 }
982
983 /* set up target bitmap */
984 if ( target->pixel_mode == FT_PIXEL_MODE_NONE )
985 {
986 /* create new empty bitmap */
987 target->width = final_width;
988 target->rows = final_rows;
989 target->pixel_mode = FT_PIXEL_MODE_BGRA;
990 target->pitch = (int)final_width * 4;
991 target->num_grays = 256;
992
993 if ( FT_LONG_MAX / target->pitch < (int)target->rows )
994 {
995 FT_TRACE5(( "FT_Blend_Bitmap: target bitmap too large (%d x %d)\n",
996 final_width, final_rows ));
997 return FT_THROW( Invalid_Argument );
998 }
999
1000 if ( FT_ALLOC( target->buffer, target->pitch * (int)target->rows ) )
1001 return error;
1002
1003 free_target_bitmap_on_error = 1;
1004 }
1005 else if ( target->width != final_width ||
1006 target->rows != final_rows )
1007 {
1008 /* adjust old bitmap to enlarged size */
1009 int pitch, new_pitch;
1010
1011 unsigned char* buffer = NULL;
1012
1013
1014 pitch = target->pitch;
1015 if ( pitch < 0 )
1016 pitch = -pitch;
1017
1018 new_pitch = (int)final_width * 4;
1019
1020 if ( FT_LONG_MAX / new_pitch < (int)final_rows )
1021 {
1022 FT_TRACE5(( "FT_Blend_Bitmap: target bitmap too large (%d x %d)\n",
1023 final_width, final_rows ));
1024 return FT_THROW( Invalid_Argument );
1025 }
1026
1027 /* TODO: provide an in-buffer solution for large bitmaps */
1028 /* to avoid allocation of a new buffer */
1029 if ( FT_ALLOC( buffer, new_pitch * (int)final_rows ) )
1030 goto Error;
1031
1032 /* copy data to new buffer */
1033 x = target_llx >> 6;
1034 y = target_lly >> 6;
1035
1036 /* the bitmap flow is from top to bottom, */
1037 /* but y is measured from bottom to top */
1038 if ( target->pitch < 0 )
1039 {
1040 /* XXX */
1041 }
1042 else
1043 {
1044 unsigned char* p =
1045 target->buffer;
1046 unsigned char* q =
1047 buffer +
1048 ( final_rows - y - target->rows ) * new_pitch +
1049 x * 4;
1050 unsigned char* limit_p =
1051 p + pitch * (int)target->rows;
1052
1053
1054 while ( p < limit_p )
1055 {
1056 FT_MEM_COPY( q, p, pitch );
1057
1058 p += pitch;
1059 q += new_pitch;
1060 }
1061 }
1062
1063 FT_FREE( target->buffer );
1064
1065 target->width = final_width;
1066 target->rows = final_rows;
1067
1068 if ( target->pitch < 0 )
1069 target->pitch = -new_pitch;
1070 else
1071 target->pitch = new_pitch;
1072
1073 target->buffer = buffer;
1074 }
1075
1076 /* adjust source bitmap if necessary */
1077 if ( source_->pixel_mode != FT_PIXEL_MODE_GRAY )
1078 {
1079 FT_Bitmap_Init( &source_bitmap );
1080 error = FT_Bitmap_Convert( library, source_, &source_bitmap, 1 );
1081 if ( error )
1082 goto Error;
1083
1084 source = &source_bitmap;
1085 free_source_bitmap = 1;
1086 }
1087 else
1088 source = source_;
1089
1090 /* do blending; the code below returns pre-multiplied channels, */
1091 /* similar to what FreeType gets from `CBDT' tables */
1092 x = source_llx >> 6;
1093 y = source_lly >> 6;
1094
1095 /* the bitmap flow is from top to bottom, */
1096 /* but y is measured from bottom to top */
1097 if ( target->pitch < 0 )
1098 {
1099 /* XXX */
1100 }
1101 else
1102 {
1103 unsigned char* p =
1104 source->buffer;
1105 unsigned char* q =
1106 target->buffer +
1107 ( target->rows - y - source->rows ) * target->pitch +
1108 x * 4;
1109 unsigned char* limit_p =
1110 p + source->pitch * (int)source->rows;
1111
1112
1113 while ( p < limit_p )
1114 {
1115 unsigned char* r = p;
1116 unsigned char* s = q;
1117 unsigned char* limit_r = r + source->width;
1118
1119
1120 while ( r < limit_r )
1121 {
1122 int aa = *r++;
1123 int fa = color.alpha * aa / 255;
1124
1125 int fb = color.blue * fa / 255;
1126 int fg = color.green * fa / 255;
1127 int fr = color.red * fa / 255;
1128
1129 int ba2 = 255 - fa;
1130
1131 int bb = s[0];
1132 int bg = s[1];
1133 int br = s[2];
1134 int ba = s[3];
1135
1136
1137 *s++ = (unsigned char)( bb * ba2 / 255 + fb );
1138 *s++ = (unsigned char)( bg * ba2 / 255 + fg );
1139 *s++ = (unsigned char)( br * ba2 / 255 + fr );
1140 *s++ = (unsigned char)( ba * ba2 / 255 + fa );
1141 }
1142
1143 p += source->pitch;
1144 q += target->pitch;
1145 }
1146 }
1147
1148 atarget_offset->x = final_llx;
1149 atarget_offset->y = final_lly + ( final_rows << 6 );
1150
1151 Error:
1152 if ( error && free_target_bitmap_on_error )
1154
1155 if ( free_source_bitmap )
1156 FT_Bitmap_Done( library, &source_bitmap );
1157
1158 return error;
1159 }
1160
1161
1162 /* documentation is in ftbitmap.h */
1163
1166 {
1167 if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP &&
1168 !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
1169 {
1172
1173
1175 error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
1176 if ( error )
1177 return error;
1178
1179 slot->bitmap = bitmap;
1180 slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
1181 }
1182
1183 return FT_Err_Ok;
1184 }
1185
1186
1187 /* documentation is in ftbitmap.h */
1188
1191 FT_Bitmap *bitmap )
1192 {
1194
1195
1196 if ( !library )
1197 return FT_THROW( Invalid_Library_Handle );
1198
1199 if ( !bitmap )
1200 return FT_THROW( Invalid_Argument );
1201
1203
1204 FT_FREE( bitmap->buffer );
1206
1207 return FT_Err_Ok;
1208 }
1209
1210
1211/* END */
#define write
Definition: acwin.h:97
_Check_return_ _Ret_maybenull_ _In_ size_t alignment
Definition: align.cpp:48
BOOL Error
Definition: chkdsk.c:66
r l[0]
Definition: byte_order.h:168
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
FT_Library library
Definition: cffdrivr.c:661
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
DWORD bpp
Definition: surface.c:185
unsigned char
Definition: typeof.h:29
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
size_t const old_size
Definition: expand.cpp:65
return FT_Err_Ok
Definition: ftbbox.c:527
FT_GlyphSlot_Own_Bitmap(FT_GlyphSlot slot)
Definition: ftbitmap.c:1165
FT_Bitmap_Convert(FT_Library library, const FT_Bitmap *source, FT_Bitmap *target, FT_Int alignment)
Definition: ftbitmap.c:524
FT_Bitmap_New(FT_Bitmap *abitmap)
Definition: ftbitmap.c:54
FT_Bitmap_Done(FT_Library library, FT_Bitmap *bitmap)
Definition: ftbitmap.c:1190
static const FT_Bitmap null_bitmap
Definition: ftbitmap.c:38
FT_Bitmap_Embolden(FT_Library library, FT_Bitmap *bitmap, FT_Pos xStrength, FT_Pos yStrength)
Definition: ftbitmap.c:308
FT_Bitmap_Copy(FT_Library library, const FT_Bitmap *source, FT_Bitmap *target)
Definition: ftbitmap.c:64
FT_Bitmap_Blend(FT_Library library, const FT_Bitmap *source_, const FT_Vector source_offset_, FT_Bitmap *target, FT_Vector *atarget_offset, FT_Color color)
Definition: ftbitmap.c:840
FT_Bitmap_Init(FT_Bitmap *abitmap)
Definition: ftbitmap.c:44
static FT_Error ft_bitmap_assure_buffer(FT_Memory memory, FT_Bitmap *bitmap, FT_UInt xpixels, FT_UInt ypixels)
Definition: ftbitmap.c:160
static FT_Byte ft_gray_for_premultiplied_srgb_bgra(const FT_Byte *bgra)
Definition: ftbitmap.c:468
FT_BEGIN_HEADER struct FT_Color_ FT_Color
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:494
#define FT_TRACE5(varformat)
Definition: ftdebug.h:190
#define FT_THROW(e)
Definition: ftdebug.h:241
@ FT_PIXEL_MODE_GRAY2
Definition: ftimage.h:186
@ FT_PIXEL_MODE_LCD_V
Definition: ftimage.h:189
@ FT_PIXEL_MODE_MONO
Definition: ftimage.h:184
@ FT_PIXEL_MODE_NONE
Definition: ftimage.h:183
@ FT_PIXEL_MODE_GRAY
Definition: ftimage.h:185
@ FT_PIXEL_MODE_LCD
Definition: ftimage.h:188
@ FT_PIXEL_MODE_BGRA
Definition: ftimage.h:190
@ FT_PIXEL_MODE_GRAY4
Definition: ftimage.h:187
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_QALLOC_MULT(ptr, count, item_size)
Definition: ftmemory.h:321
#define FT_QREALLOC(ptr, cursz, newsz)
Definition: ftmemory.h:318
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:302
#define FT_FREE(ptr)
Definition: ftmemory.h:328
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:244
#define FT_QALLOC(ptr, size)
Definition: ftmemory.h:315
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:228
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:235
#define FT_ABS(a)
Definition: ftobjs.h:73
#define FT_PIX_FLOOR(x)
Definition: ftobjs.h:91
#define FT_MIN(a, b)
Definition: ftobjs.h:70
#define FT_PIX_ROUND(x)
Definition: ftobjs.h:92
#define FT_MAX(a, b)
Definition: ftobjs.h:71
#define FT_GLYPH_OWN_BITMAP
Definition: ftobjs.h:423
#define FT_LONG_MIN
Definition: ftstdlib.h:66
#define FT_ULONG_MAX
Definition: ftstdlib.h:68
#define FT_INT_MAX
Definition: ftstdlib.h:63
#define FT_LONG_MAX
Definition: ftstdlib.h:67
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:65
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:299
unsigned int FT_UInt
Definition: fttypes.h:231
signed int FT_Int
Definition: fttypes.h:220
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble t
Definition: gl.h:2047
GLint GLint GLsizei width
Definition: gl.h:1546
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
GLenum GLint GLuint mask
Definition: glext.h:6028
GLint limit
Definition: glext.h:10326
GLuint in
Definition: glext.h:9616
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define ss
Definition: i386-dis.c:441
#define a
Definition: ke_i.h:78
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:116
#define shift
Definition: input.c:1755
f_args fa
Definition: format.c:280
FT_Memory memory
Definition: ftobjs.h:897
FT_Pos x
Definition: ftimage.h:78
FT_Pos y
Definition: ftimage.h:79
Definition: vfat.h:185
Definition: uimain.c:89
uint32 width
Definition: uimain.c:91
Definition: parser.c:49
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define const
Definition: zconf.h:233