|
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; |