ReactOS 0.4.16-dev-2332-g4cba65d
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-2020 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
20
21#include <freetype/ftbitmap.h>
22#include <freetype/ftimage.h>
24
25
26 /**************************************************************************
27 *
28 * The macro FT_COMPONENT is used in trace mode. It is an implicit
29 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
30 * messages during execution.
31 */
32#undef FT_COMPONENT
33#define FT_COMPONENT bitmap
34
35
36 static
37 const FT_Bitmap null_bitmap = { 0, 0, 0, NULL, 0, 0, 0, NULL };
38
39
40 /* documentation is in ftbitmap.h */
41
42 FT_EXPORT_DEF( void )
44 {
45 if ( abitmap )
46 *abitmap = null_bitmap;
47 }
48
49
50 /* deprecated function name; retained for ABI compatibility */
51
52 FT_EXPORT_DEF( void )
54 {
55 if ( abitmap )
56 *abitmap = null_bitmap;
57 }
58
59
60 /* documentation is in ftbitmap.h */
61
66 {
69
70 FT_Int pitch;
72
73 FT_Int source_pitch_sign, target_pitch_sign;
74
75
76 if ( !library )
77 return FT_THROW( Invalid_Library_Handle );
78
79 if ( !source || !target )
80 return FT_THROW( Invalid_Argument );
81
82 if ( source == target )
83 return FT_Err_Ok;
84
85 source_pitch_sign = source->pitch < 0 ? -1 : 1;
86 target_pitch_sign = target->pitch < 0 ? -1 : 1;
87
88 if ( !source->buffer )
89 {
90 *target = *source;
91 if ( source_pitch_sign != target_pitch_sign )
92 target->pitch = -target->pitch;
93
94 return FT_Err_Ok;
95 }
96
98 pitch = source->pitch;
99
100 if ( pitch < 0 )
101 pitch = -pitch;
102 size = (FT_ULong)pitch * source->rows;
103
104 if ( target->buffer )
105 {
106 FT_Int target_pitch = target->pitch;
107 FT_ULong target_size;
108
109
110 if ( target_pitch < 0 )
111 target_pitch = -target_pitch;
112 target_size = (FT_ULong)target_pitch * target->rows;
113
114 if ( target_size != size )
115 (void)FT_QREALLOC( target->buffer, target_size, size );
116 }
117 else
118 (void)FT_QALLOC( target->buffer, size );
119
120 if ( !error )
121 {
122 unsigned char *p;
123
124
125 p = target->buffer;
126 *target = *source;
127 target->buffer = p;
128
129 if ( source_pitch_sign == target_pitch_sign )
130 FT_MEM_COPY( target->buffer, source->buffer, size );
131 else
132 {
133 /* take care of bitmap flow */
134 FT_UInt i;
135 FT_Byte* s = source->buffer;
136 FT_Byte* t = target->buffer;
137
138
139 t += (FT_ULong)pitch * ( target->rows - 1 );
140
141 for ( i = target->rows; i > 0; i-- )
142 {
143 FT_ARRAY_COPY( t, s, pitch );
144
145 s += pitch;
146 t -= pitch;
147 }
148 }
149 }
150
151 return error;
152 }
153
154
155 /* Enlarge `bitmap' horizontally and vertically by `xpixels' */
156 /* and `ypixels', respectively. */
157
158 static FT_Error
161 FT_UInt xpixels,
162 FT_UInt ypixels )
163 {
165 unsigned int pitch;
166 unsigned int new_pitch;
167 FT_UInt bpp;
169 unsigned char* buffer = NULL;
170
171
172 width = bitmap->width;
173 height = bitmap->rows;
174 pitch = (unsigned int)FT_ABS( bitmap->pitch );
175
176 switch ( bitmap->pixel_mode )
177 {
179 bpp = 1;
180 new_pitch = ( width + xpixels + 7 ) >> 3;
181 break;
183 bpp = 2;
184 new_pitch = ( width + xpixels + 3 ) >> 2;
185 break;
187 bpp = 4;
188 new_pitch = ( width + xpixels + 1 ) >> 1;
189 break;
193 bpp = 8;
194 new_pitch = width + xpixels;
195 break;
196 default:
197 return FT_THROW( Invalid_Glyph_Format );
198 }
199
200 /* if no need to allocate memory */
201 if ( ypixels == 0 && new_pitch <= pitch )
202 {
203 /* zero the padding */
204 FT_UInt bit_width = pitch * 8;
205 FT_UInt bit_last = ( width + xpixels ) * bpp;
206
207
208 if ( bit_last < bit_width )
209 {
210 FT_Byte* line = bitmap->buffer + ( bit_last >> 3 );
211 FT_Byte* end = bitmap->buffer + pitch;
212 FT_UInt shift = bit_last & 7;
213 FT_UInt mask = 0xFF00U >> shift;
215
216
217 for ( ; count > 0; count--, line += pitch, end += pitch )
218 {
219 FT_Byte* write = line;
220
221
222 if ( shift > 0 )
223 {
224 write[0] = (FT_Byte)( write[0] & mask );
225 write++;
226 }
227 if ( write < end )
229 }
230 }
231
232 return FT_Err_Ok;
233 }
234
235 /* otherwise allocate new buffer */
236 if ( FT_QALLOC_MULT( buffer, bitmap->rows + ypixels, new_pitch ) )
237 return error;
238
239 /* new rows get added at the top of the bitmap, */
240 /* thus take care of the flow direction */
241 if ( bitmap->pitch > 0 )
242 {
243 FT_UInt len = ( width * bpp + 7 ) >> 3;
244
245 unsigned char* in = bitmap->buffer;
246 unsigned char* out = buffer;
247
248 unsigned char* limit = bitmap->buffer + pitch * bitmap->rows;
249 unsigned int delta = new_pitch - len;
250
251
252 FT_MEM_ZERO( out, new_pitch * ypixels );
253 out += new_pitch * ypixels;
254
255 while ( in < limit )
256 {
257 FT_MEM_COPY( out, in, len );
258 in += pitch;
259 out += len;
260
261 /* we use FT_QALLOC_MULT, which doesn't zero out the buffer; */
262 /* consequently, we have to manually zero out the remaining bytes */
263 FT_MEM_ZERO( out, delta );
264 out += delta;
265 }
266 }
267 else
268 {
269 FT_UInt len = ( width * bpp + 7 ) >> 3;
270
271 unsigned char* in = bitmap->buffer;
272 unsigned char* out = buffer;
273
274 unsigned char* limit = bitmap->buffer + pitch * bitmap->rows;
275 unsigned int delta = new_pitch - len;
276
277
278 while ( in < limit )
279 {
280 FT_MEM_COPY( out, in, len );
281 in += pitch;
282 out += len;
283
284 FT_MEM_ZERO( out, delta );
285 out += delta;
286 }
287
288 FT_MEM_ZERO( out, new_pitch * ypixels );
289 }
290
291 FT_FREE( bitmap->buffer );
292 bitmap->buffer = buffer;
293
294 /* set pitch only, width and height are left untouched */
295 if ( bitmap->pitch < 0 )
296 bitmap->pitch = -(int)new_pitch;
297 else
298 bitmap->pitch = (int)new_pitch;
299
300 return FT_Err_Ok;
301 }
302
303
304 /* documentation is in ftbitmap.h */
305
309 FT_Pos xStrength,
310 FT_Pos yStrength )
311 {
313 unsigned char* p;
314 FT_Int i, x, pitch;
315 FT_UInt y;
316 FT_Int xstr, ystr;
317
318
319 if ( !library )
320 return FT_THROW( Invalid_Library_Handle );
321
322 if ( !bitmap || !bitmap->buffer )
323 return FT_THROW( Invalid_Argument );
324
325 if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
326 ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
327 return FT_THROW( Invalid_Argument );
328
329 xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
330 ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
331
332 if ( xstr == 0 && ystr == 0 )
333 return FT_Err_Ok;
334 else if ( xstr < 0 || ystr < 0 )
335 return FT_THROW( Invalid_Argument );
336
337 switch ( bitmap->pixel_mode )
338 {
341 {
342 FT_Bitmap tmp;
343
344
345 /* convert to 8bpp */
346 FT_Bitmap_Init( &tmp );
347 error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 );
348 if ( error )
349 return error;
350
352 *bitmap = tmp;
353 }
354 break;
355
357 if ( xstr > 8 )
358 xstr = 8;
359 break;
360
362 xstr *= 3;
363 break;
364
366 ystr *= 3;
367 break;
368
370 /* We don't embolden color glyphs. */
371 return FT_Err_Ok;
372 }
373
375 (FT_UInt)xstr, (FT_UInt)ystr );
376 if ( error )
377 return error;
378
379 /* take care of bitmap flow */
380 pitch = bitmap->pitch;
381 if ( pitch > 0 )
382 p = bitmap->buffer + pitch * ystr;
383 else
384 {
385 pitch = -pitch;
386 p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 );
387 }
388
389 /* for each row */
390 for ( y = 0; y < bitmap->rows; y++ )
391 {
392 /*
393 * Horizontally:
394 *
395 * From the last pixel on, make each pixel or'ed with the
396 * `xstr' pixels before it.
397 */
398 for ( x = pitch - 1; x >= 0; x-- )
399 {
400 unsigned char tmp;
401
402
403 tmp = p[x];
404 for ( i = 1; i <= xstr; i++ )
405 {
406 if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO )
407 {
408 p[x] |= tmp >> i;
409
410 /* the maximum value of 8 for `xstr' comes from here */
411 if ( x > 0 )
412 p[x] |= p[x - 1] << ( 8 - i );
413
414#if 0
415 if ( p[x] == 0xFF )
416 break;
417#endif
418 }
419 else
420 {
421 if ( x - i >= 0 )
422 {
423 if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
424 {
425 p[x] = (unsigned char)( bitmap->num_grays - 1 );
426 break;
427 }
428 else
429 {
430 p[x] = (unsigned char)( p[x] + p[x - i] );
431 if ( p[x] == bitmap->num_grays - 1 )
432 break;
433 }
434 }
435 else
436 break;
437 }
438 }
439 }
440
441 /*
442 * Vertically:
443 *
444 * Make the above `ystr' rows or'ed with it.
445 */
446 for ( x = 1; x <= ystr; x++ )
447 {
448 unsigned char* q;
449
450
451 q = p - bitmap->pitch * x;
452 for ( i = 0; i < pitch; i++ )
453 q[i] |= p[i];
454 }
455
456 p += bitmap->pitch;
457 }
458
459 bitmap->width += (FT_UInt)xstr;
460 bitmap->rows += (FT_UInt)ystr;
461
462 return FT_Err_Ok;
463 }
464
465
466 static FT_Byte
468 {
469 FT_UInt a = bgra[3];
470 FT_UInt l;
471
472
473 /* Short-circuit transparent color to avoid division by zero. */
474 if ( !a )
475 return 0;
476
477 /*
478 * Luminosity for sRGB is defined using ~0.2126,0.7152,0.0722
479 * coefficients for RGB channels *on the linear colors*.
480 * A gamma of 2.2 is fair to assume. And then, we need to
481 * undo the premultiplication too.
482 *
483 * https://accessibility.kde.org/hsl-adjusted.php
484 *
485 * We do the computation with integers only, applying a gamma of 2.0.
486 * We guarantee 32-bit arithmetic to avoid overflow but the resulting
487 * luminosity fits into 16 bits.
488 *
489 */
490
491 l = ( 4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] +
492 46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] +
493 13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16;
494
495 /*
496 * Final transparency can be determined as follows.
497 *
498 * - If alpha is zero, we want 0.
499 * - If alpha is zero and luminosity is zero, we want 255.
500 * - If alpha is zero and luminosity is one, we want 0.
501 *
502 * So the formula is a * (1 - l) = a - l * a.
503 *
504 * We still need to undo premultiplication by dividing l by a*a.
505 *
506 */
507
508 return (FT_Byte)( a - l / a );
509 }
510
511
512 /* documentation is in ftbitmap.h */
513
514#ifdef __REACTOS__
516 FT_Bitmap_Convert_ReactOS_Hack( FT_Library library,
517 const FT_Bitmap *source,
520 FT_Bool hack )
521#else
527#endif
528 {
531
532 FT_Byte* s;
533 FT_Byte* t;
534
535
536 if ( !library )
537 return FT_THROW( Invalid_Library_Handle );
538
539 if ( !source || !target )
540 return FT_THROW( Invalid_Argument );
541
543
544 switch ( source->pixel_mode )
545 {
553 {
554 FT_Int pad, old_target_pitch, target_pitch;
556
557
558 old_target_pitch = target->pitch;
559 if ( old_target_pitch < 0 )
560 old_target_pitch = -old_target_pitch;
561
562 old_size = target->rows * (FT_UInt)old_target_pitch;
563
564 target->pixel_mode = FT_PIXEL_MODE_GRAY;
565 target->rows = source->rows;
566 target->width = source->width;
567
568 pad = 0;
569 if ( alignment > 0 )
570 {
571 pad = (FT_Int)source->width % alignment;
572 if ( pad != 0 )
573 pad = alignment - pad;
574 }
575
576 target_pitch = (FT_Int)source->width + pad;
577
578 if ( target_pitch > 0 &&
579 (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
580 return FT_THROW( Invalid_Argument );
581
582 if ( FT_QREALLOC( target->buffer,
583 old_size, target->rows * (FT_UInt)target_pitch ) )
584 return error;
585
586 target->pitch = target->pitch < 0 ? -target_pitch : target_pitch;
587 }
588 break;
589
590 default:
591 error = FT_THROW( Invalid_Argument );
592 }
593
594 s = source->buffer;
595 t = target->buffer;
596
597 /* take care of bitmap flow */
598 if ( source->pitch < 0 )
599 s -= source->pitch * (FT_Int)( source->rows - 1 );
600 if ( target->pitch < 0 )
601 t -= target->pitch * (FT_Int)( target->rows - 1 );
602
603 switch ( source->pixel_mode )
604 {
606 {
607 FT_UInt i;
608
609
610 target->num_grays = 2;
611
612 for ( i = source->rows; i > 0; i-- )
613 {
614 FT_Byte* ss = s;
615 FT_Byte* tt = t;
616 FT_UInt j;
617
618
619 /* get the full bytes */
620 for ( j = source->width >> 3; j > 0; j-- )
621 {
622 FT_Int val = ss[0]; /* avoid a byte->int cast on each line */
623
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: (%ld, %ld) -- (%ld, %ld); %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: (%ld, %ld) -- (%ld, %ld); %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 if ( final_width && final_rows )
967 FT_TRACE5(( " final bitmap: (%ld, %ld) -- (%ld, %ld); %d x %d\n",
968 final_llx / 64, final_lly / 64,
969 final_urx / 64, final_ury / 64,
970 final_width, final_rows ));
971 else
972 FT_TRACE5(( " final bitmap: empty\n" ));
973#endif /* FT_DEBUG_LEVEL_TRACE */
974
975 if ( !( final_width && final_rows ) )
976 return FT_Err_Ok; /* nothing to do */
977
978 /* for blending, set offset vector of final bitmap */
979 /* temporarily to (0,0) */
980 source_llx -= final_llx;
981 source_lly -= final_lly;
982
983 if ( target->width && target->rows )
984 {
985 target_llx -= final_llx;
986 target_lly -= final_lly;
987 }
988
989 /* set up target bitmap */
990 if ( target->pixel_mode == FT_PIXEL_MODE_NONE )
991 {
992 /* create new empty bitmap */
993 target->width = final_width;
994 target->rows = final_rows;
995 target->pixel_mode = FT_PIXEL_MODE_BGRA;
996 target->pitch = (int)final_width * 4;
997 target->num_grays = 256;
998
999 if ( FT_LONG_MAX / target->pitch < (int)target->rows )
1000 {
1001 FT_TRACE5(( "FT_Blend_Bitmap: target bitmap too large (%d x %d)\n",
1002 final_width, final_rows ));
1003 return FT_THROW( Invalid_Argument );
1004 }
1005
1006 if ( FT_ALLOC( target->buffer, target->pitch * (int)target->rows ) )
1007 return error;
1008
1009 free_target_bitmap_on_error = 1;
1010 }
1011 else if ( target->width != final_width ||
1012 target->rows != final_rows )
1013 {
1014 /* adjust old bitmap to enlarged size */
1015 int pitch, new_pitch;
1016
1017 unsigned char* buffer = NULL;
1018
1019
1020 pitch = target->pitch;
1021
1022 if ( pitch < 0 )
1023 pitch = -pitch;
1024
1025 new_pitch = (int)final_width * 4;
1026
1027 if ( FT_LONG_MAX / new_pitch < (int)final_rows )
1028 {
1029 FT_TRACE5(( "FT_Blend_Bitmap: target bitmap too large (%d x %d)\n",
1030 final_width, final_rows ));
1031 return FT_THROW( Invalid_Argument );
1032 }
1033
1034 /* TODO: provide an in-buffer solution for large bitmaps */
1035 /* to avoid allocation of a new buffer */
1036 if ( FT_ALLOC( buffer, new_pitch * (int)final_rows ) )
1037 goto Error;
1038
1039 /* copy data to new buffer */
1040 x = target_llx >> 6;
1041 y = target_lly >> 6;
1042
1043 /* the bitmap flow is from top to bottom, */
1044 /* but y is measured from bottom to top */
1045 if ( target->pitch < 0 )
1046 {
1047 /* XXX */
1048 }
1049 else
1050 {
1051 unsigned char* p =
1052 target->buffer;
1053 unsigned char* q =
1054 buffer +
1055 ( final_rows - y - target->rows ) * new_pitch +
1056 x * 4;
1057 unsigned char* limit_p =
1058 p + pitch * (int)target->rows;
1059
1060
1061 while ( p < limit_p )
1062 {
1063 FT_MEM_COPY( q, p, pitch );
1064
1065 p += pitch;
1066 q += new_pitch;
1067 }
1068 }
1069
1070 FT_FREE( target->buffer );
1071
1072 target->width = final_width;
1073 target->rows = final_rows;
1074
1075 if ( target->pitch < 0 )
1076 target->pitch = -new_pitch;
1077 else
1078 target->pitch = new_pitch;
1079
1080 target->buffer = buffer;
1081 }
1082
1083 /* adjust source bitmap if necessary */
1084 if ( source_->pixel_mode != FT_PIXEL_MODE_GRAY )
1085 {
1086 FT_Bitmap_Init( &source_bitmap );
1087 error = FT_Bitmap_Convert( library, source_, &source_bitmap, 1 );
1088 if ( error )
1089 goto Error;
1090
1091 source = &source_bitmap;
1092 free_source_bitmap = 1;
1093 }
1094 else
1095 source = source_;
1096
1097 /* do blending; the code below returns pre-multiplied channels, */
1098 /* similar to what FreeType gets from `CBDT' tables */
1099 x = source_llx >> 6;
1100 y = source_lly >> 6;
1101
1102 /* the bitmap flow is from top to bottom, */
1103 /* but y is measured from bottom to top */
1104 if ( target->pitch < 0 )
1105 {
1106 /* XXX */
1107 }
1108 else
1109 {
1110 unsigned char* p =
1111 source->buffer;
1112 unsigned char* q =
1113 target->buffer +
1114 ( target->rows - y - source->rows ) * target->pitch +
1115 x * 4;
1116 unsigned char* limit_p =
1117 p + source->pitch * (int)source->rows;
1118
1119
1120 while ( p < limit_p )
1121 {
1122 unsigned char* r = p;
1123 unsigned char* s = q;
1124 unsigned char* limit_r = r + source->width;
1125
1126
1127 while ( r < limit_r )
1128 {
1129 int aa = *r++;
1130 int fa = color.alpha * aa / 255;
1131
1132 int fb = color.blue * fa / 255;
1133 int fg = color.green * fa / 255;
1134 int fr = color.red * fa / 255;
1135
1136 int ba2 = 255 - fa;
1137
1138 int bb = s[0];
1139 int bg = s[1];
1140 int br = s[2];
1141 int ba = s[3];
1142
1143
1144 *s++ = (unsigned char)( bb * ba2 / 255 + fb );
1145 *s++ = (unsigned char)( bg * ba2 / 255 + fg );
1146 *s++ = (unsigned char)( br * ba2 / 255 + fr );
1147 *s++ = (unsigned char)( ba * ba2 / 255 + fa );
1148 }
1149
1150 p += source->pitch;
1151 q += target->pitch;
1152 }
1153 }
1154
1155 atarget_offset->x = final_llx;
1156 atarget_offset->y = final_lly + ( final_rows << 6 );
1157
1158 Error:
1159 if ( error && free_target_bitmap_on_error )
1161
1162 if ( free_source_bitmap )
1163 FT_Bitmap_Done( library, &source_bitmap );
1164
1165 return error;
1166 }
1167
1168
1169 /* documentation is in ftbitmap.h */
1170
1173 {
1174 if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP &&
1175 !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
1176 {
1179
1180
1182 error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
1183 if ( error )
1184 return error;
1185
1186 slot->bitmap = bitmap;
1187 slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
1188 }
1189
1190 return FT_Err_Ok;
1191 }
1192
1193
1194 /* documentation is in ftbitmap.h */
1195
1198 FT_Bitmap *bitmap )
1199 {
1201
1202
1203 if ( !library )
1204 return FT_THROW( Invalid_Library_Handle );
1205
1206 if ( !bitmap )
1207 return FT_THROW( Invalid_Argument );
1208
1210
1211 FT_FREE( bitmap->buffer );
1213
1214 return FT_Err_Ok;
1215 }
1216
1217
1218/* 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:660
#define FT_EXPORT_DEF(x)
#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:526
FT_GlyphSlot_Own_Bitmap(FT_GlyphSlot slot)
Definition: ftbitmap.c:1172
FT_Bitmap_Convert(FT_Library library, const FT_Bitmap *source, FT_Bitmap *target, FT_Int alignment)
Definition: ftbitmap.c:523
FT_Bitmap_New(FT_Bitmap *abitmap)
Definition: ftbitmap.c:53
FT_Bitmap_Done(FT_Library library, FT_Bitmap *bitmap)
Definition: ftbitmap.c:1197
static const FT_Bitmap null_bitmap
Definition: ftbitmap.c:37
FT_Bitmap_Embolden(FT_Library library, FT_Bitmap *bitmap, FT_Pos xStrength, FT_Pos yStrength)
Definition: ftbitmap.c:307
FT_Bitmap_Copy(FT_Library library, const FT_Bitmap *source, FT_Bitmap *target)
Definition: ftbitmap.c:63
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:43
static FT_Error ft_bitmap_assure_buffer(FT_Memory memory, FT_Bitmap *bitmap, FT_UInt xpixels, FT_UInt ypixels)
Definition: ftbitmap.c:159
static FT_Byte ft_gray_for_premultiplied_srgb_bgra(const FT_Byte *bgra)
Definition: ftbitmap.c:467
FT_BEGIN_HEADER struct FT_Color_ FT_Color
#define FT_TRACE5(varformat)
Definition: ftdebug.h:192
#define FT_THROW(e)
Definition: ftdebug.h:243
@ FT_PIXEL_MODE_GRAY2
Definition: ftimage.h:185
@ FT_PIXEL_MODE_LCD_V
Definition: ftimage.h:188
@ FT_PIXEL_MODE_MONO
Definition: ftimage.h:183
@ FT_PIXEL_MODE_NONE
Definition: ftimage.h:182
@ FT_PIXEL_MODE_GRAY
Definition: ftimage.h:184
@ FT_PIXEL_MODE_LCD
Definition: ftimage.h:187
@ FT_PIXEL_MODE_BGRA
Definition: ftimage.h:189
@ FT_PIXEL_MODE_GRAY4
Definition: ftimage.h:186
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:57
#define FT_QALLOC_MULT(ptr, count, item_size)
Definition: ftmemory.h:330
#define FT_QREALLOC(ptr, cursz, newsz)
Definition: ftmemory.h:327
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:311
#define FT_FREE(ptr)
Definition: ftmemory.h:337
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:253
#define FT_QALLOC(ptr, size)
Definition: ftmemory.h:324
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:237
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:244
#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:421
#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:64
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
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:122
#define shift
Definition: input.c:1755
f_args fa
Definition: format.c:280
FT_Memory memory
Definition: ftobjs.h:895
FT_Pos x
Definition: ftimage.h:77
FT_Pos y
Definition: ftimage.h:78
Definition: vfat.h:185
Definition: uimain.c:89
uint32 width
Definition: uimain.c:91
Definition: parser.c:49
Definition: tools.h:99
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define const
Definition: zconf.h:233