Lines 66-71
Link Here
|
66 |
#include FT_TYPE1_TABLES_H |
66 |
#include FT_TYPE1_TABLES_H |
67 |
#include FT_GLYPH_H |
67 |
#include FT_GLYPH_H |
68 |
|
68 |
|
|
|
69 |
#include FT_LCD_FILTER_H |
70 |
|
69 |
QT_BEGIN_NAMESPACE |
71 |
QT_BEGIN_NAMESPACE |
70 |
|
72 |
|
71 |
/* |
73 |
/* |
Lines 100-105
Link Here
|
100 |
return (HB_Error)error; |
102 |
return (HB_Error)error; |
101 |
} |
103 |
} |
102 |
|
104 |
|
|
|
105 |
// ------------- copied from David Turner's lcd patches ----------------------- |
106 |
|
107 |
/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot |
108 |
* into a different format. For example, we want to convert a |
109 |
* FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit |
110 |
* ARGB or ABGR bitmap. |
111 |
* |
112 |
* this function prepares a target descriptor for this operation. |
113 |
* |
114 |
* input :: target bitmap descriptor. The function will set its |
115 |
* 'width', 'rows' and 'pitch' fields, and only these |
116 |
* |
117 |
* slot :: the glyph slot containing the source bitmap. this |
118 |
* function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP |
119 |
* |
120 |
* mode :: the requested final rendering mode. supported values are |
121 |
* MONO, NORMAL (i.e. gray), LCD and LCD_V |
122 |
* |
123 |
* the function returns the size in bytes of the corresponding buffer, |
124 |
* it's up to the caller to allocate the corresponding memory block |
125 |
* before calling _fill_xrender_bitmap |
126 |
* |
127 |
* it also returns -1 in case of error (e.g. incompatible arguments, |
128 |
* like trying to convert a gray bitmap into a monochrome one) |
129 |
*/ |
130 |
static int |
131 |
_compute_xrender_bitmap_size( FT_Bitmap* target, |
132 |
FT_GlyphSlot slot, |
133 |
FT_Render_Mode mode ) |
134 |
{ |
135 |
FT_Bitmap* ftbit; |
136 |
int width, height, pitch; |
137 |
|
138 |
if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) |
139 |
return -1; |
140 |
|
141 |
// compute the size of the final bitmap |
142 |
ftbit = &slot->bitmap; |
143 |
|
144 |
width = ftbit->width; |
145 |
height = ftbit->rows; |
146 |
pitch = (width+3) & ~3; |
147 |
|
148 |
switch ( ftbit->pixel_mode ) |
149 |
{ |
150 |
case FT_PIXEL_MODE_MONO: |
151 |
if ( mode == FT_RENDER_MODE_MONO ) |
152 |
{ |
153 |
pitch = (((width+31) & ~31) >> 3); |
154 |
break; |
155 |
} |
156 |
/* fall-through */ |
157 |
|
158 |
case FT_PIXEL_MODE_GRAY: |
159 |
if ( mode == FT_RENDER_MODE_LCD || |
160 |
mode == FT_RENDER_MODE_LCD_V ) |
161 |
{ |
162 |
/* each pixel is replicated into a 32-bit ARGB value */ |
163 |
pitch = width*4; |
164 |
} |
165 |
break; |
166 |
|
167 |
case FT_PIXEL_MODE_LCD: |
168 |
if ( mode != FT_RENDER_MODE_LCD ) |
169 |
return -1; |
170 |
|
171 |
/* horz pixel triplets are packed into 32-bit ARGB values */ |
172 |
width /= 3; |
173 |
pitch = width*4; |
174 |
break; |
175 |
|
176 |
case FT_PIXEL_MODE_LCD_V: |
177 |
if ( mode != FT_RENDER_MODE_LCD_V ) |
178 |
return -1; |
179 |
|
180 |
/* vert pixel triplets are packed into 32-bit ARGB values */ |
181 |
height /= 3; |
182 |
pitch = width*4; |
183 |
break; |
184 |
|
185 |
default: /* unsupported source format */ |
186 |
return -1; |
187 |
} |
188 |
|
189 |
target->width = width; |
190 |
target->rows = height; |
191 |
target->pitch = pitch; |
192 |
target->buffer = NULL; |
193 |
|
194 |
return pitch * height; |
195 |
} |
196 |
|
197 |
/* this functions converts the glyph bitmap found in a FT_GlyphSlot |
198 |
* into a different format (see _compute_xrender_bitmap_size) |
199 |
* |
200 |
* you should call this function after _compute_xrender_bitmap_size |
201 |
* |
202 |
* target :: target bitmap descriptor. Note that its 'buffer' pointer |
203 |
* must point to memory allocated by the caller |
204 |
* |
205 |
* slot :: the glyph slot containing the source bitmap |
206 |
* |
207 |
* mode :: the requested final rendering mode |
208 |
* |
209 |
* bgr :: boolean, set if BGR or VBGR pixel ordering is needed |
210 |
*/ |
211 |
static void |
212 |
_fill_xrender_bitmap( FT_Bitmap* target, |
213 |
FT_GlyphSlot slot, |
214 |
FT_Render_Mode mode, |
215 |
int bgr ) |
216 |
{ |
217 |
FT_Bitmap* ftbit = &slot->bitmap; |
218 |
|
219 |
{ |
220 |
unsigned char* srcLine = ftbit->buffer; |
221 |
unsigned char* dstLine = target->buffer; |
222 |
int src_pitch = ftbit->pitch; |
223 |
int width = target->width; |
224 |
int height = target->rows; |
225 |
int pitch = target->pitch; |
226 |
int subpixel; |
227 |
int h; |
228 |
|
229 |
subpixel = ( mode == FT_RENDER_MODE_LCD || |
230 |
mode == FT_RENDER_MODE_LCD_V ); |
231 |
|
232 |
if ( src_pitch < 0 ) |
233 |
srcLine -= src_pitch*(ftbit->rows-1); |
234 |
|
235 |
switch ( ftbit->pixel_mode ) |
236 |
{ |
237 |
case FT_PIXEL_MODE_MONO: |
238 |
if ( subpixel ) /* convert mono to ARGB32 values */ |
239 |
{ |
240 |
for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) |
241 |
{ |
242 |
int x; |
243 |
|
244 |
for ( x = 0; x < width; x++ ) |
245 |
{ |
246 |
if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) ) |
247 |
((unsigned int*)dstLine)[x] = 0xffffffffU; |
248 |
} |
249 |
} |
250 |
} |
251 |
else if ( mode == FT_RENDER_MODE_NORMAL ) /* convert mono to 8-bit gray */ |
252 |
{ |
253 |
for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) |
254 |
{ |
255 |
int x; |
256 |
|
257 |
for ( x = 0; x < width; x++ ) |
258 |
{ |
259 |
if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) ) |
260 |
dstLine[x] = 0xff; |
261 |
} |
262 |
} |
263 |
} |
264 |
else /* copy mono to mono */ |
265 |
{ |
266 |
int bytes = (width+7) >> 3; |
267 |
|
268 |
for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) |
269 |
memcpy( dstLine, srcLine, bytes ); |
270 |
} |
271 |
break; |
272 |
|
273 |
case FT_PIXEL_MODE_GRAY: |
274 |
if ( subpixel ) /* convert gray to ARGB32 values */ |
275 |
{ |
276 |
for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) |
277 |
{ |
278 |
int x; |
279 |
unsigned int* dst = (unsigned int*)dstLine; |
280 |
|
281 |
for ( x = 0; x < width; x++ ) |
282 |
{ |
283 |
unsigned int pix = srcLine[x]; |
284 |
|
285 |
pix |= (pix << 8); |
286 |
pix |= (pix << 16); |
287 |
|
288 |
dst[x] = pix; |
289 |
} |
290 |
} |
291 |
} |
292 |
else /* copy gray into gray */ |
293 |
{ |
294 |
for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) |
295 |
memcpy( dstLine, srcLine, width ); |
296 |
} |
297 |
break; |
298 |
|
299 |
case FT_PIXEL_MODE_LCD: |
300 |
if ( !bgr ) |
301 |
{ |
302 |
/* convert horizontal RGB into ARGB32 */ |
303 |
for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) |
304 |
{ |
305 |
int x; |
306 |
unsigned char* src = srcLine; |
307 |
unsigned int* dst = (unsigned int*)dstLine; |
308 |
|
309 |
for ( x = 0; x < width; x++, src += 3 ) |
310 |
{ |
311 |
unsigned int pix; |
312 |
|
313 |
pix = ((unsigned int)src[0] << 16) | |
314 |
((unsigned int)src[1] << 8) | |
315 |
((unsigned int)src[2] ) | |
316 |
((unsigned int)src[1] << 24) ; |
317 |
|
318 |
dst[x] = pix; |
319 |
} |
320 |
} |
321 |
} |
322 |
else |
323 |
{ |
324 |
/* convert horizontal BGR into ARGB32 */ |
325 |
for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch ) |
326 |
{ |
327 |
int x; |
328 |
unsigned char* src = srcLine; |
329 |
unsigned int* dst = (unsigned int*)dstLine; |
330 |
|
331 |
for ( x = 0; x < width; x++, src += 3 ) |
332 |
{ |
333 |
unsigned int pix; |
334 |
|
335 |
pix = ((unsigned int)src[2] << 16) | |
336 |
((unsigned int)src[1] << 8) | |
337 |
((unsigned int)src[0] ) | |
338 |
((unsigned int)src[1] << 24) ; |
339 |
|
340 |
dst[x] = pix; |
341 |
} |
342 |
} |
343 |
} |
344 |
break; |
345 |
|
346 |
default: /* FT_PIXEL_MODE_LCD_V */ |
347 |
/* convert vertical RGB into ARGB32 */ |
348 |
if ( !bgr ) |
349 |
{ |
350 |
for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch ) |
351 |
{ |
352 |
int x; |
353 |
unsigned char* src = srcLine; |
354 |
unsigned int* dst = (unsigned int*)dstLine; |
355 |
|
356 |
for ( x = 0; x < width; x++, src += 1 ) |
357 |
{ |
358 |
unsigned int pix; |
359 |
|
360 |
pix = ((unsigned int)src[0] << 16) | |
361 |
((unsigned int)src[src_pitch] << 8) | |
362 |
((unsigned int)src[src_pitch*2] ) | |
363 |
((unsigned int)src[src_pitch] << 24) ; |
364 |
|
365 |
dst[x] = pix; |
366 |
} |
367 |
} |
368 |
} |
369 |
else |
370 |
{ |
371 |
for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch ) |
372 |
{ |
373 |
int x; |
374 |
unsigned char* src = srcLine; |
375 |
unsigned int* dst = (unsigned int*)dstLine; |
376 |
|
377 |
for ( x = 0; x < width; x++, src += 1 ) |
378 |
{ |
379 |
unsigned int pix; |
380 |
|
381 |
pix = ((unsigned int)src[src_pitch*2] << 16) | |
382 |
((unsigned int)src[src_pitch] << 8) | |
383 |
((unsigned int)src[0] ) | |
384 |
((unsigned int)src[src_pitch] << 24) ; |
385 |
|
386 |
dst[x] = pix; |
387 |
} |
388 |
} |
389 |
} |
390 |
} |
391 |
} |
392 |
} |
393 |
|
394 |
|
103 |
// -------------------------- Freetype support ------------------------------ |
395 |
// -------------------------- Freetype support ------------------------------ |
104 |
|
396 |
|
105 |
class QtFreetypeData |
397 |
class QtFreetypeData |
Lines 499-510
Link Here
|
499 |
delete [] data; |
791 |
delete [] data; |
500 |
} |
792 |
} |
501 |
|
793 |
|
502 |
static const uint subpixel_filter[3][3] = { |
|
|
503 |
{ 180, 60, 16 }, |
504 |
{ 38, 180, 38 }, |
505 |
{ 16, 60, 180 } |
506 |
}; |
507 |
|
508 |
QFontEngineFT::QFontEngineFT(const QFontDef &fd) |
794 |
QFontEngineFT::QFontEngineFT(const QFontDef &fd) |
509 |
{ |
795 |
{ |
510 |
fontDef = fd; |
796 |
fontDef = fd; |
Lines 631-646
Link Here
|
631 |
QFontEngineFT::GlyphInfo info; |
917 |
QFontEngineFT::GlyphInfo info; |
632 |
|
918 |
|
633 |
Q_ASSERT(format != Format_None); |
919 |
Q_ASSERT(format != Format_None); |
634 |
bool hsubpixel = false; |
|
|
635 |
int vfactor = 1; |
636 |
int load_flags = FT_LOAD_DEFAULT | default_load_flags; |
920 |
int load_flags = FT_LOAD_DEFAULT | default_load_flags; |
|
|
921 |
FT_Render_Mode mode = FT_RENDER_MODE_NORMAL; |
637 |
if (outline_drawing) { |
922 |
if (outline_drawing) { |
638 |
load_flags = FT_LOAD_NO_BITMAP; |
923 |
load_flags = FT_LOAD_NO_BITMAP; |
|
|
924 |
} else if (format == Format_Mono) { |
925 |
mode = FT_RENDER_MODE_MONO; |
639 |
} else if (format == Format_A32) { |
926 |
} else if (format == Format_A32) { |
640 |
if (subpixelType == QFontEngineFT::Subpixel_RGB || subpixelType == QFontEngineFT::Subpixel_BGR) { |
927 |
if (subpixelType == QFontEngineFT::Subpixel_RGB || subpixelType == QFontEngineFT::Subpixel_BGR) { |
641 |
hsubpixel = true; |
928 |
mode = FT_RENDER_MODE_LCD; |
642 |
} else if (subpixelType == QFontEngineFT::Subpixel_VRGB || subpixelType == QFontEngineFT::Subpixel_VBGR) { |
929 |
} else if (subpixelType == QFontEngineFT::Subpixel_VRGB || subpixelType == QFontEngineFT::Subpixel_VBGR) { |
643 |
vfactor = 3; |
930 |
mode = FT_RENDER_MODE_LCD_V; |
644 |
} |
931 |
} |
645 |
|
932 |
|
646 |
} |
933 |
} |
Lines 677-911
Link Here
|
677 |
|
964 |
|
678 |
FT_GlyphSlot slot = face->glyph; |
965 |
FT_GlyphSlot slot = face->glyph; |
679 |
|
966 |
|
680 |
int left = slot->metrics.horiBearingX; |
967 |
if (slot->format != FT_GLYPH_FORMAT_BITMAP) { |
681 |
int right = slot->metrics.horiBearingX + slot->metrics.width; |
968 |
FT_Library library = slot->library; |
682 |
int top = slot->metrics.horiBearingY; |
969 |
FT_Library_SetLcdFilter( library, FT_LCD_FILTER_DEFAULT ); |
683 |
int bottom = slot->metrics.horiBearingY - slot->metrics.height; |
970 |
FT_Render_Glyph( slot, mode ); |
684 |
if(transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { |
971 |
FT_Library_SetLcdFilter( library, FT_LCD_FILTER_NONE ); |
685 |
int l, r, t, b; |
972 |
} |
686 |
FT_Vector vector; |
973 |
|
687 |
vector.x = left; |
974 |
FT_Bitmap bitmap; |
688 |
vector.y = top; |
975 |
int size = _compute_xrender_bitmap_size( &bitmap, slot, mode ); |
689 |
FT_Vector_Transform(&vector, &matrix); |
976 |
if (size < 0) |
690 |
l = r = vector.x; |
977 |
return 0; |
691 |
t = b = vector.y; |
978 |
|
692 |
vector.x = right; |
979 |
info.width = bitmap.width; |
693 |
vector.y = top; |
980 |
info.height = bitmap.rows; |
694 |
FT_Vector_Transform(&vector, &matrix); |
981 |
info.x = - slot->bitmap_left; |
695 |
if (l > vector.x) l = vector.x; |
982 |
info.y = slot->bitmap_top; |
696 |
if (r < vector.x) r = vector.x; |
|
|
697 |
if (t < vector.y) t = vector.y; |
698 |
if (b > vector.y) b = vector.y; |
699 |
vector.x = right; |
700 |
vector.y = bottom; |
701 |
FT_Vector_Transform(&vector, &matrix); |
702 |
if (l > vector.x) l = vector.x; |
703 |
if (r < vector.x) r = vector.x; |
704 |
if (t < vector.y) t = vector.y; |
705 |
if (b > vector.y) b = vector.y; |
706 |
vector.x = left; |
707 |
vector.y = bottom; |
708 |
FT_Vector_Transform(&vector, &matrix); |
709 |
if (l > vector.x) l = vector.x; |
710 |
if (r < vector.x) r = vector.x; |
711 |
if (t < vector.y) t = vector.y; |
712 |
if (b > vector.y) b = vector.y; |
713 |
left = l; |
714 |
right = r; |
715 |
top = t; |
716 |
bottom = b; |
717 |
} |
718 |
left = FLOOR(left); |
719 |
right = CEIL(right); |
720 |
bottom = FLOOR(bottom); |
721 |
top = CEIL(top); |
722 |
|
723 |
int hpixels = TRUNC(right - left); |
724 |
if (hsubpixel) |
725 |
hpixels = hpixels*3 + 8; |
726 |
info.width = hpixels; |
727 |
info.height = TRUNC(top - bottom); |
728 |
info.x = -TRUNC(left); |
729 |
info.y = TRUNC(top); |
730 |
info.xOff = TRUNC(ROUND(slot->advance.x)); |
983 |
info.xOff = TRUNC(ROUND(slot->advance.x)); |
731 |
info.yOff = 0; |
984 |
info.yOff = 0; |
732 |
if (hsubpixel) { |
|
|
733 |
info.width /= 3; |
734 |
info.x += 1; |
735 |
} |
736 |
|
985 |
|
737 |
int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 : |
|
|
738 |
(format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4)); |
739 |
int size = pitch * info.height; |
740 |
uchar *glyph_buffer = new uchar[size]; |
986 |
uchar *glyph_buffer = new uchar[size]; |
741 |
|
987 |
memset(glyph_buffer, 0, size); |
742 |
if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { |
988 |
bitmap.buffer = glyph_buffer; |
743 |
FT_Bitmap bitmap; |
989 |
_fill_xrender_bitmap(&bitmap, slot, mode, |
744 |
bitmap.rows = info.height*vfactor; |
990 |
(subpixelType == QFontEngineFT::Subpixel_BGR || |
745 |
bitmap.width = hpixels; |
991 |
subpixelType == QFontEngineFT::Subpixel_VBGR)); |
746 |
bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3); |
|
|
747 |
if (!hsubpixel && vfactor == 1) |
748 |
bitmap.buffer = glyph_buffer; |
749 |
else |
750 |
bitmap.buffer = new uchar[bitmap.rows*bitmap.pitch]; |
751 |
memset(bitmap.buffer, 0, bitmap.rows*bitmap.pitch); |
752 |
bitmap.pixel_mode = format == Format_Mono ? ft_pixel_mode_mono : ft_pixel_mode_grays; |
753 |
FT_Matrix matrix; |
754 |
matrix.xx = (hsubpixel ? 3 : 1) << 16; |
755 |
matrix.yy = vfactor << 16; |
756 |
matrix.yx = matrix.xy = 0; |
757 |
|
758 |
FT_Outline_Transform(&slot->outline, &matrix); |
759 |
FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor); |
760 |
FT_Outline_Get_Bitmap(qt_getFreetype(), &slot->outline, &bitmap); |
761 |
if (hsubpixel) { |
762 |
Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); |
763 |
Q_ASSERT(antialias); |
764 |
const uchar *src = bitmap.buffer; |
765 |
uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch]; |
766 |
uchar *c = convoluted; |
767 |
// convolute the bitmap with a triangle filter to get rid of color fringes |
768 |
// If we take account for a gamma value of 2, we end up with |
769 |
// weights of 1, 4, 9, 4, 1. We use an approximation of 1, 3, 8, 3, 1 here, |
770 |
// as this nicely sums up to 16 :) |
771 |
int h = info.height; |
772 |
while (h--) { |
773 |
c[0] = c[1] = 0; |
774 |
// |
775 |
for (int x = 2; x < bitmap.width - 2; ++x) { |
776 |
uint sum = src[x-2] + 3*src[x-1] + 8*src[x] + 3*src[x+1] + src[x+2]; |
777 |
c[x] = (uchar) (sum >> 4); |
778 |
} |
779 |
c[bitmap.width - 2] = c[bitmap.width -1] = 0; |
780 |
src += bitmap.pitch; |
781 |
c += bitmap.pitch; |
782 |
} |
783 |
|
784 |
uint *dst = (uint *)glyph_buffer; |
785 |
src = convoluted; |
786 |
h = info.height; |
787 |
if (subpixelType == QFontEngineFT::Subpixel_RGB) { |
788 |
while (h--) { |
789 |
uint *dd = dst; |
790 |
for (int x = 1; x < bitmap.width - 1; x += 3) { |
791 |
uint red = src[x]; |
792 |
uint green = src[x+1]; |
793 |
uint blue = src[x+2]; |
794 |
uint alpha = green; |
795 |
uint res = (alpha << 24) + (red << 16) + (green << 8) + blue; |
796 |
*dd = res; |
797 |
++dd; |
798 |
} |
799 |
dst += info.width; |
800 |
src += bitmap.pitch; |
801 |
} |
802 |
} else { |
803 |
while (h--) { |
804 |
uint *dd = dst; |
805 |
for (int x = 1; x < bitmap.width - 1; x += 3) { |
806 |
uint blue = src[x]; |
807 |
uint green = src[x+1]; |
808 |
uint red = src[x+2]; |
809 |
uint alpha = green; |
810 |
uint res = (alpha << 24) + (red << 16) + (green << 8) + blue; |
811 |
*dd = res; |
812 |
++dd; |
813 |
} |
814 |
dst += info.width; |
815 |
src += bitmap.pitch; |
816 |
} |
817 |
} |
818 |
delete [] convoluted; |
819 |
delete [] bitmap.buffer; |
820 |
} else if (vfactor != 1) { |
821 |
uchar *src = bitmap.buffer; |
822 |
size = info.width * 4 * info.height; |
823 |
uint *dst = (uint *)glyph_buffer; |
824 |
int h = info.height; |
825 |
if (subpixelType == QFontEngineFT::Subpixel_VRGB) { |
826 |
while (h--) { |
827 |
for (int x = 0; x < info.width; x++) { |
828 |
uint red = src[x]; |
829 |
uint green = src[x+bitmap.pitch]; |
830 |
uint blue = src[x+2*bitmap.pitch]; |
831 |
uint high = (red*subpixel_filter[0][0] + green*subpixel_filter[0][1] + blue*subpixel_filter[0][2]) >> 8; |
832 |
uint mid = (red*subpixel_filter[1][0] + green*subpixel_filter[1][1] + blue*subpixel_filter[1][2]) >> 8; |
833 |
uint low = (red*subpixel_filter[2][0] + green*subpixel_filter[2][1] + blue*subpixel_filter[2][2]) >> 8; |
834 |
uint res = (mid << 24) + (high << 16) + (mid << 8) + low; |
835 |
dst[x] = res; |
836 |
} |
837 |
dst += info.width; |
838 |
src += 3*bitmap.pitch; |
839 |
} |
840 |
} else { |
841 |
while (h--) { |
842 |
for (int x = 0; x < info.width; x++) { |
843 |
uint blue = src[x]; |
844 |
uint green = src[x+bitmap.pitch]; |
845 |
uint red = src[x+2*bitmap.pitch]; |
846 |
uint high = (red*subpixel_filter[0][0] + green*subpixel_filter[0][1] + blue*subpixel_filter[0][2]) >> 8; |
847 |
uint mid = (red*subpixel_filter[1][0] + green*subpixel_filter[1][1] + blue*subpixel_filter[1][2]) >> 8; |
848 |
uint low = (red*subpixel_filter[2][0] + green*subpixel_filter[2][1] + blue*subpixel_filter[2][2]) >> 8; |
849 |
uint res = (mid << 24) + (high << 16) + (mid << 8) + low; |
850 |
dst[x] = res; |
851 |
} |
852 |
dst += info.width; |
853 |
src += 3*bitmap.pitch; |
854 |
} |
855 |
} |
856 |
delete [] bitmap.buffer; |
857 |
} |
858 |
} else if (slot->format == FT_GLYPH_FORMAT_BITMAP) { |
859 |
Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO); |
860 |
uchar *src = slot->bitmap.buffer; |
861 |
uchar *dst = glyph_buffer; |
862 |
int h = slot->bitmap.rows; |
863 |
if (format == Format_Mono) { |
864 |
int bytes = ((info.width + 7) & ~7) >> 3; |
865 |
while (h--) { |
866 |
memcpy (dst, src, bytes); |
867 |
dst += pitch; |
868 |
src += slot->bitmap.pitch; |
869 |
} |
870 |
} else { |
871 |
if (hsubpixel) { |
872 |
while (h--) { |
873 |
uint *dd = (uint *)dst; |
874 |
*dd++ = 0; |
875 |
for (int x = 0; x < slot->bitmap.width; x++) { |
876 |
uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000); |
877 |
*dd++ = a; |
878 |
} |
879 |
*dd++ = 0; |
880 |
dst += pitch; |
881 |
src += slot->bitmap.pitch; |
882 |
} |
883 |
} else if (vfactor != 1) { |
884 |
while (h--) { |
885 |
uint *dd = (uint *)dst; |
886 |
for (int x = 0; x < slot->bitmap.width; x++) { |
887 |
uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000); |
888 |
*dd++ = a; |
889 |
} |
890 |
dst += pitch; |
891 |
src += slot->bitmap.pitch; |
892 |
} |
893 |
} else { |
894 |
while (h--) { |
895 |
for (int x = 0; x < slot->bitmap.width; x++) { |
896 |
unsigned char a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00); |
897 |
dst[x] = a; |
898 |
} |
899 |
dst += pitch; |
900 |
src += slot->bitmap.pitch; |
901 |
} |
902 |
} |
903 |
} |
904 |
} else { |
905 |
qWarning("QFontEngine: Glyph neither outline nor bitmap format=%d", slot->format); |
906 |
delete [] glyph_buffer; |
907 |
return 0; |
908 |
} |
909 |
|
992 |
|
910 |
bool large_glyph = (((signed char)(slot->linearHoriAdvance>>16) != slot->linearHoriAdvance>>16) |
993 |
bool large_glyph = (((signed char)(slot->linearHoriAdvance>>16) != slot->linearHoriAdvance>>16) |
911 |
|| ((uchar)(info.width) != info.width) |
994 |
|| ((uchar)(info.width) != info.width) |
Lines 928-936
Link Here
|
928 |
|
1011 |
|
929 |
g->linearAdvance = slot->linearHoriAdvance >> 10; |
1012 |
g->linearAdvance = slot->linearHoriAdvance >> 10; |
930 |
g->width = info.width; |
1013 |
g->width = info.width; |
931 |
g->height = TRUNC(top - bottom); |
1014 |
g->height = info.height; |
932 |
g->x = -info.x; |
1015 |
g->x = -info.x; |
933 |
g->y = TRUNC(top); |
1016 |
g->y = info.y; |
934 |
g->advance = TRUNC(ROUND(slot->advance.x)); |
1017 |
g->advance = TRUNC(ROUND(slot->advance.x)); |
935 |
g->format = format; |
1018 |
g->format = format; |
936 |
delete [] g->data; |
1019 |
delete [] g->data; |