Changeset 561 for trunk/src/gui/text/qfontengine_ft.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/gui/text/qfontengine_ft.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtGui module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 54 54 #include <private/qpdf_p.h> 55 55 #include <private/qharfbuzz_p.h> 56 57 #include <private/qpdf_p.h>58 56 59 57 #include "qfontengine_ft_p.h" … … 194 192 * One font file can contain more than one font (bold/italic for example) 195 193 * find the right one and return it. 194 * 195 * Returns the freetype face or 0 in case of an empty file or any other problems 196 * (like not being able to open the file) 196 197 */ 197 198 QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) … … 205 206 206 207 QFreetypeFace *freetype = freetypeData->faces.value(face_id, 0); 207 if (!freetype) { 208 freetype = new QFreetypeFace; 208 if (freetype) { 209 freetype->ref.ref(); 210 } else { 211 QScopedPointer<QFreetypeFace> newFreetype(new QFreetypeFace); 209 212 FT_Face face; 210 213 QFile file(QString::fromUtf8(face_id.filename)); … … 215 218 idx.remove(0, 14); // remove ':qmemoryfonts/' 216 219 bool ok = false; 217 freetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));220 newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok)); 218 221 if (!ok) 219 freetype->fontData = QByteArray();222 newFreetype->fontData = QByteArray(); 220 223 } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) { 221 224 if (!file.open(QIODevice::ReadOnly)) { 222 delete freetype;223 225 return 0; 224 226 } 225 freetype->fontData = file.readAll(); 226 } 227 if (!freetype->fontData.isEmpty()) { 228 if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)freetype->fontData.constData(), freetype->fontData.size(), face_id.index, &face)) { 229 delete freetype; 227 newFreetype->fontData = file.readAll(); 228 } 229 if (!newFreetype->fontData.isEmpty()) { 230 if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) { 230 231 return 0; 231 232 } 232 233 } else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) { 233 delete freetype;234 234 return 0; 235 235 } 236 freetype->face = face; 237 238 freetype->hbFace = qHBNewFace(face, hb_getSFntTable); 239 freetype->ref = 0; 240 freetype->xsize = 0; 241 freetype->ysize = 0; 242 freetype->matrix.xx = 0x10000; 243 freetype->matrix.yy = 0x10000; 244 freetype->matrix.xy = 0; 245 freetype->matrix.yx = 0; 246 freetype->unicode_map = 0; 247 freetype->symbol_map = 0; 236 newFreetype->face = face; 237 238 newFreetype->hbFace = qHBNewFace(face, hb_getSFntTable); 239 Q_CHECK_PTR(newFreetype->hbFace); 240 newFreetype->ref = 1; 241 newFreetype->xsize = 0; 242 newFreetype->ysize = 0; 243 newFreetype->matrix.xx = 0x10000; 244 newFreetype->matrix.yy = 0x10000; 245 newFreetype->matrix.xy = 0; 246 newFreetype->matrix.yx = 0; 247 newFreetype->unicode_map = 0; 248 newFreetype->symbol_map = 0; 248 249 #ifndef QT_NO_FONTCONFIG 249 freetype->charset = 0;250 #endif 251 252 memset( freetype->cmapCache, 0, sizeof(freetype->cmapCache));253 254 for (int i = 0; i < freetype->face->num_charmaps; ++i) {255 FT_CharMap cm = freetype->face->charmaps[i];250 newFreetype->charset = 0; 251 #endif 252 253 memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache)); 254 255 for (int i = 0; i < newFreetype->face->num_charmaps; ++i) { 256 FT_CharMap cm = newFreetype->face->charmaps[i]; 256 257 switch(cm->encoding) { 257 258 case FT_ENCODING_UNICODE: 258 freetype->unicode_map = cm;259 newFreetype->unicode_map = cm; 259 260 break; 260 261 case FT_ENCODING_APPLE_ROMAN: 261 262 case FT_ENCODING_ADOBE_LATIN_1: 262 if (! freetype->unicode_map || freetype->unicode_map->encoding != FT_ENCODING_UNICODE)263 freetype->unicode_map = cm;263 if (!newFreetype->unicode_map || newFreetype->unicode_map->encoding != FT_ENCODING_UNICODE) 264 newFreetype->unicode_map = cm; 264 265 break; 265 266 case FT_ENCODING_ADOBE_CUSTOM: 266 267 case FT_ENCODING_MS_SYMBOL: 267 if (! freetype->symbol_map)268 freetype->symbol_map = cm;268 if (!newFreetype->symbol_map) 269 newFreetype->symbol_map = cm; 269 270 break; 270 271 default: … … 273 274 } 274 275 275 if (!FT_IS_SCALABLE( freetype->face) && freetype->face->num_fixed_sizes == 1)276 FT_Set_Char_Size (face, X_SIZE( freetype->face, 0), Y_SIZE(freetype->face, 0), 0, 0);276 if (!FT_IS_SCALABLE(newFreetype->face) && newFreetype->face->num_fixed_sizes == 1) 277 FT_Set_Char_Size (face, X_SIZE(newFreetype->face, 0), Y_SIZE(newFreetype->face, 0), 0, 0); 277 278 # if 0 278 279 FcChar8 *name; 279 280 FcPatternGetString(pattern, FC_FAMILY, 0, &name); 280 281 qDebug("%s: using maps: default: %x unicode: %x, symbol: %x", name, 281 freetype->face->charmap ? freetype->face->charmap->encoding : 0,282 freetype->unicode_map ? freetype->unicode_map->encoding : 0,283 freetype->symbol_map ? freetype->symbol_map->encoding : 0);282 newFreetype->face->charmap ? newFreetype->face->charmap->encoding : 0, 283 newFreetype->unicode_map ? newFreetype->unicode_map->encoding : 0, 284 newFreetype->symbol_map ? newFreetype->symbol_map->encoding : 0); 284 285 285 286 for (int i = 0; i < 256; i += 8) 286 287 qDebug(" %x: %d %d %d %d %d %d %d %d", i, 287 FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), 288 FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), 289 FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), 290 FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i)); 291 #endif 292 293 FT_Set_Charmap(freetype->face, freetype->unicode_map); 294 freetypeData->faces.insert(face_id, freetype); 295 } 296 freetype->ref.ref(); 288 FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), 289 FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), 290 FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), 291 FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i)); 292 #endif 293 294 FT_Set_Charmap(newFreetype->face, newFreetype->unicode_map); 295 QT_TRY { 296 freetypeData->faces.insert(face_id, newFreetype.data()); 297 } QT_CATCH(...) { 298 newFreetype.take()->release(face_id); 299 // we could return null in principle instead of throwing 300 QT_RETHROW; 301 } 302 freetype = newFreetype.take(); 303 } 297 304 return freetype; 298 305 } … … 308 315 FcCharSetDestroy(charset); 309 316 #endif 310 freetypeData->faces.take(face_id); 317 if(freetypeData->faces.contains(face_id)) 318 freetypeData->faces.take(face_id); 311 319 delete this; 312 320 } … … 320 328 void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing) 321 329 { 322 *ysize = fontDef.pixelSize << 6;330 *ysize = qRound(fontDef.pixelSize * 64); 323 331 *xsize = *ysize * fontDef.stretch / 100; 324 332 *outline_drawing = false; … … 380 388 p.leading = QFixed::fromFixed(face->size->metrics.height - face->size->metrics.ascender + face->size->metrics.descender); 381 389 p.emSquare = face->size->metrics.y_ppem; 382 p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.); 390 // p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.); 391 p.boundingBox = QRectF(0, -p.ascent.toReal(), 392 face->size->metrics.max_advance/64, (p.ascent + p.descent).toReal() ); 383 393 } 384 394 p.italicAngle = 0; … … 609 619 transform = false; 610 620 antialias = true; 621 freetype = 0; 611 622 default_load_flags = 0; 612 623 default_hint_style = HintNone; … … 614 625 lcdFilterType = 0; 615 626 #if defined(FT_LCD_FILTER_H) 616 lcdFilterType = (int) FT_LCD_FILTER_DEFAULT;627 lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT); 617 628 #endif 618 629 defaultFormat = Format_None; … … 639 650 defaultFormat = format; 640 651 this->antialias = antialias; 652 641 653 if (!antialias) 642 654 glyphFormat = QFontEngineGlyphCache::Raster_Mono; 655 else if (format == Format_A8) 656 glyphFormat = QFontEngineGlyphCache::Raster_A8; 657 else if (format == Format_A32) 658 glyphFormat = QFontEngineGlyphCache::Raster_RGBMask; 659 643 660 face_id = faceId; 644 661 freetype = QFreetypeFace::getFace(face_id); … … 695 712 696 713 metrics = face->size->metrics; 714 697 715 #if defined(Q_WS_QWS) 698 716 /* … … 738 756 739 757 // apply our matrix to this, but note that the metrics will not be affected by this. 740 FT_Matrix matrix = freetype->matrix;741 758 FT_Face face = lockFace(); 742 matrix = this->matrix;759 FT_Matrix matrix = this->matrix; 743 760 FT_Matrix_Multiply(&set->transformationMatrix, &matrix); 744 761 FT_Set_Transform(face, &matrix, 0); … … 1205 1222 QFixed QFontEngineFT::descent() const 1206 1223 { 1207 return QFixed::fromFixed(-metrics.descender); 1224 // subtract a pixel to work around QFontMetrics's built-in + 1 1225 return QFixed::fromFixed(-metrics.descender - 64); 1208 1226 } 1209 1227 … … 1381 1399 1382 1400 for (int i = 0; i < num_glyphs; ++i) { 1383 if (!gs->glyph_data.contains(glyphs[i])1384 || gs->glyph_data.value(glyphs[i])->format != format) {1401 Glyph *glyph = gs->glyph_data.value(glyphs[i]); 1402 if (glyph == 0 || glyph->format != format) { 1385 1403 if (!face) { 1386 1404 face = lockFace(); … … 1521 1539 return false; 1522 1540 } 1541 1542 #if !defined(QT_NO_FONTCONFIG) 1543 extern QMutex *qt_fontdatabase_mutex(); 1544 QMutex *mtx = 0; 1545 #endif 1523 1546 1524 1547 bool mirrored = flags & QTextEngine::RightToLeft; … … 1534 1557 glyph_t glyph; 1535 1558 #if !defined(QT_NO_FONTCONFIG) 1559 if (!mtx) { 1560 mtx = qt_fontdatabase_mutex(); 1561 mtx->lock(); 1562 } 1563 1536 1564 if (FcCharSetHasChar(freetype->charset, uc)) { 1537 1565 #else … … 1562 1590 uc = QChar::mirroredChar(uc); 1563 1591 glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0; 1564 if (!glyphs->glyphs[glyph_pos] 1592 if (!glyphs->glyphs[glyph_pos]) { 1565 1593 #if !defined(QT_NO_FONTCONFIG) 1566 && FcCharSetHasChar(freetype->charset, uc) 1567 #endif 1568 ) { 1569 redo: 1570 glyph_t glyph = FT_Get_Char_Index(face, uc); 1571 if (!glyph && (uc == 0xa0 || uc == 0x9)) { 1572 uc = 0x20; 1573 goto redo; 1594 if (!mtx) { 1595 mtx = qt_fontdatabase_mutex(); 1596 mtx->lock(); 1574 1597 } 1575 glyphs->glyphs[glyph_pos] = glyph; 1576 if (uc < QFreetypeFace::cmapCacheSize) 1577 freetype->cmapCache[uc] = glyph; 1598 1599 if (FcCharSetHasChar(freetype->charset, uc)) 1600 #endif 1601 { 1602 redo: 1603 glyph_t glyph = FT_Get_Char_Index(face, uc); 1604 if (!glyph && (uc == 0xa0 || uc == 0x9)) { 1605 uc = 0x20; 1606 goto redo; 1607 } 1608 glyphs->glyphs[glyph_pos] = glyph; 1609 if (uc < QFreetypeFace::cmapCacheSize) 1610 freetype->cmapCache[uc] = glyph; 1611 } 1578 1612 } 1579 1613 ++glyph_pos; … … 1583 1617 *nglyphs = glyph_pos; 1584 1618 glyphs->numGlyphs = glyph_pos; 1619 1620 #if !defined(QT_NO_FONTCONFIG) 1621 if (mtx) 1622 mtx->unlock(); 1623 #endif 1585 1624 1586 1625 if (flags & QTextEngine::GlyphIndicesOnly) … … 1789 1828 GlyphFormat glyph_format = antialias ? Format_A8 : Format_Mono; 1790 1829 1791 Glyph *glyph = loadGlyph(g, glyph_format); 1792 if (!glyph) 1793 return QImage(); 1830 Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format); 1831 if (!glyph) { 1832 unlockFace(); 1833 return QFontEngine::alphaMapForGlyph(g); 1834 } 1794 1835 1795 1836 const int pitch = antialias ? (glyph->width + 3) & ~3 : ((glyph->width + 31)/32) * 4; … … 1817 1858 } 1818 1859 1860 QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, int margin, const QTransform &t) 1861 { 1862 if (t.type() > QTransform::TxTranslate) 1863 return QFontEngine::alphaRGBMapForGlyph(g, margin, t); 1864 1865 lockFace(); 1866 1867 GlyphFormat glyph_format = Format_A32; 1868 1869 Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format); 1870 if (!glyph) { 1871 unlockFace(); 1872 return QFontEngine::alphaRGBMapForGlyph(g, margin, t); 1873 } 1874 1875 QImage img(glyph->width, glyph->height, QImage::Format_RGB32); 1876 memcpy(img.bits(), glyph->data, 4 * glyph->width * glyph->height); 1877 unlockFace(); 1878 1879 return img; 1880 } 1881 1819 1882 void QFontEngineFT::removeGlyphFromCache(glyph_t glyph) 1820 1883 {
Note:
See TracChangeset
for help on using the changeset viewer.