diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/dialogs/qerrormessage.cpp | 16 | ||||
-rw-r--r-- | src/gui/dialogs/qfontdialog.cpp | 2 | ||||
-rw-r--r-- | src/gui/dialogs/qmessagebox.cpp | 18 | ||||
-rw-r--r-- | src/gui/image/qtiffhandler.cpp | 31 | ||||
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_p.h | 2 | ||||
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 26 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qcocoasharedwindowmethods_mac_p.h | 8 | ||||
-rw-r--r-- | src/gui/kernel/qt_s60_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_x11.cpp | 6 | ||||
-rw-r--r-- | src/gui/painting/qgraphicssystemex_symbian.cpp | 1 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 24 | ||||
-rw-r--r-- | src/gui/styles/qs60style.cpp | 16 | ||||
-rw-r--r-- | src/gui/styles/qs60style_p.h | 2 | ||||
-rw-r--r-- | src/gui/styles/qs60style_s60.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qfont_s60.cpp | 33 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_s60.cpp | 19 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 137 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 21 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 43 |
20 files changed, 309 insertions, 106 deletions
diff --git a/src/gui/dialogs/qerrormessage.cpp b/src/gui/dialogs/qerrormessage.cpp index 890e6ca..0a6580a 100644 --- a/src/gui/dialogs/qerrormessage.cpp +++ b/src/gui/dialogs/qerrormessage.cpp @@ -249,12 +249,20 @@ QErrorMessage::QErrorMessage(QWidget * parent) d->icon->setPixmap(QMessageBox::standardIcon(QMessageBox::Information)); d->icon->setAlignment(Qt::AlignHCenter | Qt::AlignTop); #endif - grid->addWidget(d->icon, 0, 0, Qt::AlignTop); +#ifdef Q_WS_S60 + //In Symbian, messagebox icons are in LtR UIs on right. Thus, layout needs to switch icon and text columns. + const int preferredIconColumn = (QApplication::layoutDirection() == Qt::LeftToRight) ? 1 : 0; + const int preferredTextColumn = (QApplication::layoutDirection() == Qt::LeftToRight) ? 0 : 1; +#else + const int preferredIconColumn = 0; + const int preferredTextColumn = 1; +#endif + grid->addWidget(d->icon, 0, preferredIconColumn, Qt::AlignTop); d->errors = new QErrorMessageTextView(this); - grid->addWidget(d->errors, 0, 1); + grid->addWidget(d->errors, 0, preferredTextColumn); d->again = new QCheckBox(this); d->again->setChecked(true); - grid->addWidget(d->again, 1, 1, Qt::AlignTop); + grid->addWidget(d->again, 1, preferredTextColumn, Qt::AlignTop); d->ok = new QPushButton(this); #ifdef QT_SOFTKEYS_ENABLED d->okAction = new QAction(d->ok); @@ -270,7 +278,7 @@ QErrorMessage::QErrorMessage(QWidget * parent) connect(d->ok, SIGNAL(clicked()), this, SLOT(accept())); d->ok->setFocus(); grid->addWidget(d->ok, 2, 0, 1, 2, Qt::AlignCenter); - grid->setColumnStretch(1, 42); + grid->setColumnStretch(preferredTextColumn, 42); grid->setRowStretch(0, 42); d->retranslateStrings(); } diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp index 6a646ff..34b6317 100644 --- a/src/gui/dialogs/qfontdialog.cpp +++ b/src/gui/dialogs/qfontdialog.cpp @@ -160,7 +160,7 @@ QFontDialog::QFontDialog(QWidget *parent) \since 4.5 Constructs a standard font dialog with the given \a parent and specified - \a initial color. + \a initial font. */ QFontDialog::QFontDialog(const QFont &initial, QWidget *parent) : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags) diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index 7d209fb..f18fe60 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -259,8 +259,15 @@ void QMessageBoxPrivate::init(const QString &title, const QString &text) QGridLayout *grid = new QGridLayout; #ifndef Q_WS_MAC - grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop); - grid->addWidget(label, 0, 1, 1, 1); +#ifdef Q_WS_S60 + const int preferredIconColumn = (QApplication::layoutDirection() == Qt::LeftToRight) ? 1 : 0; + const int preferredTextColumn = (QApplication::layoutDirection() == Qt::LeftToRight) ? 0 : 1; +#else + const int preferredIconColumn = 0; + const int preferredTextColumn = 1; +#endif + grid->addWidget(iconLabel, 0, preferredIconColumn, 2, 1, Qt::AlignTop); + grid->addWidget(label, 0, preferredTextColumn, 1, 1); // -- leave space for information label -- grid->addWidget(buttonBox, 2, 0, 1, 2); #else @@ -2500,7 +2507,12 @@ void QMessageBox::setInformativeText(const QString &text) label->hide(); QTextBrowser *textBrowser = new QTextBrowser(this); textBrowser->setOpenExternalLinks(true); - grid->addWidget(textBrowser, 1, 1, 1, 1); +#if defined(Q_OS_SYMBIAN) + const int preferredTextColumn = (QApplication::layoutDirection() == Qt::LeftToRight) ? 0 : 1; +#else + const int preferredTextColumn = 1; +#endif + grid->addWidget(textBrowser, 1, preferredTextColumn, 1, 1); d->textBrowser = textBrowser; #else grid->addWidget(label, 1, 1, 1, 1); diff --git a/src/gui/image/qtiffhandler.cpp b/src/gui/image/qtiffhandler.cpp index 4a90e49..fd1c488 100644 --- a/src/gui/image/qtiffhandler.cpp +++ b/src/gui/image/qtiffhandler.cpp @@ -192,13 +192,19 @@ bool QTiffHandler::read(QImage *image) return false; } - // BitsPerSample defaults to 1 according to the TIFF spec. - uint16 bitPerSample; - if (!TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bitPerSample)) - bitPerSample = 1; + uint16 bitsPerSample, samplesPerPixel, bitsPerPixel; + if (!TIFFGetFieldDefaulted(tiff, TIFFTAG_BITSPERSAMPLE, &bitsPerSample)) { + TIFFClose(tiff); + return false; + } + if (!TIFFGetFieldDefaulted(tiff, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel)) { + TIFFClose(tiff); + return false; + } + bitsPerPixel = bitsPerSample * samplesPerPixel; bool grayscale = photometric == PHOTOMETRIC_MINISBLACK || photometric == PHOTOMETRIC_MINISWHITE; - if (grayscale && bitPerSample == 1) { + if (grayscale && bitsPerPixel == 1) { if (image->size() != QSize(width, height) || image->format() != QImage::Format_Mono) *image = QImage(width, height, QImage::Format_Mono); QVector<QRgb> colortable(2); @@ -220,7 +226,7 @@ bool QTiffHandler::read(QImage *image) } } } else { - if ((grayscale || photometric == PHOTOMETRIC_PALETTE) && bitPerSample == 8) { + if ((grayscale || photometric == PHOTOMETRIC_PALETTE) && bitsPerPixel == 8) { if (image->size() != QSize(width, height) || image->format() != QImage::Format_Indexed8) *image = QImage(width, height, QImage::Format_Indexed8); if (!image->isNull()) { @@ -233,14 +239,14 @@ bool QTiffHandler::read(QImage *image) } } else { // create the color table - uint16 *redTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16))); - uint16 *greenTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16))); - uint16 *blueTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16))); - if (!redTable || !greenTable || !blueTable) { + uint16 *redTable = 0; + uint16 *greenTable = 0; + uint16 *blueTable = 0; + if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) { TIFFClose(tiff); return false; } - if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) { + if (!redTable || !greenTable || !blueTable) { TIFFClose(tiff); return false; } @@ -497,6 +503,9 @@ bool QTiffHandler::write(const QImage &image) uint16 *greenTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16))); uint16 *blueTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16))); if (!redTable || !greenTable || !blueTable) { + qFree(redTable); + qFree(greenTable); + qFree(blueTable); TIFFClose(tiff); return false; } diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index e929880..9857015 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -108,6 +108,7 @@ private: bool needsInputPanel(); void commitTemporaryPreeditString(); bool isWidgetVisible(QWidget *widget, int offset = 0); + bool isPartialKeyboardSupported(); private Q_SLOTS: void ensureInputCapabilitiesChanged(); @@ -169,6 +170,7 @@ private: }; Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable); +Q_GUI_EXPORT void qt_s60_setPartialScreenAutomaticTranslation(bool enable); QT_END_NAMESPACE diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 602c734..c3d293b 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -83,6 +83,8 @@ Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable) { S60->partial_keyboard = enable; + QApplication::setAttribute(Qt::AA_S60DisablePartialScreenInputMode, !S60->partial_keyboard); + QInputContext *ic = 0; if (QApplication::focusWidget()) { ic = QApplication::focusWidget()->inputContext(); @@ -93,6 +95,11 @@ Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable) ic->update(); } +Q_GUI_EXPORT void qt_s60_setPartialScreenAutomaticTranslation(bool enable) +{ + S60->partial_keyboardAutoTranslation = enable; +} + QCoeFepInputContext::QCoeFepInputContext(QObject *parent) : QInputContext(parent), m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new @@ -111,7 +118,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_fepState->SetObjectProvider(this); int defaultFlags = EAknEditorFlagDefault; if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) { - if (S60->partial_keyboard) { + if (isPartialKeyboardSupported()) { defaultFlags |= QT_EAknEditorFlagEnablePartialScreen; } defaultFlags |= QT_EAknEditorFlagSelectionVisible; @@ -420,7 +427,8 @@ void QCoeFepInputContext::mouseHandler(int x, QMouseEvent *event) //If splitview is open and T9 word is tapped, pass the pointer event to pointer handler. //This will open the "suggested words" list. Pass pointer position always as zero, to make //full word replacement in case user makes a selection. - if (S60->partial_keyboard && S60->partialKeyboardOpen + if (isPartialKeyboardSupported() + && S60->partialKeyboardOpen && m_pointerHandler && !(currentHints & Qt::ImhNoPredictiveText) && (x > 0 && x < m_preeditString.length())) { @@ -534,6 +542,11 @@ bool QCoeFepInputContext::isWidgetVisible(QWidget *widget, int offset) return visible; } +bool QCoeFepInputContext::isPartialKeyboardSupported() +{ + return (S60->partial_keyboard || !QApplication::testAttribute(Qt::AA_S60DisablePartialScreenInputMode)); +} + // Ensure that the input widget is visible in the splitview rect. void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget) @@ -604,12 +617,13 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget) widget->resize(widget->width(), splitViewRect.height() - windowTop); } - if (gv->scene()) { + if (gv->scene() && S60->partial_keyboardAutoTranslation) { const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF(); gv->ensureVisible(microFocusRect); } } else { - translateInputWidget(); + if (S60->partial_keyboardAutoTranslation) + translateInputWidget(); } if (alwaysResize) @@ -644,7 +658,7 @@ void QCoeFepInputContext::updateHints(bool mustUpdateInputCapabilities) // we need to update its state separately. if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) { TInt currentFlags = m_fepState->Flags(); - if (S60->partial_keyboard) + if (isPartialKeyboardSupported()) currentFlags |= QT_EAknEditorFlagEnablePartialScreen; else currentFlags &= ~QT_EAknEditorFlagEnablePartialScreen; @@ -761,7 +775,7 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) flags = 0; if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) { - if (S60->partial_keyboard) + if (isPartialKeyboardSupported()) flags |= QT_EAknEditorFlagEnablePartialScreen; flags |= QT_EAknEditorFlagSelectionVisible; } diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 4552255..34ce9a8 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -1017,6 +1017,10 @@ void QApplicationPrivate::initialize() QApplicationPrivate::wheel_scroll_lines = 3; #endif +#ifdef Q_WS_S60 + q->setAttribute(Qt::AA_S60DisablePartialScreenInputMode); +#endif + if (qt_is_gui_used) initializeMultitouch(); } diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 3e8ce4e..a2eb484 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -327,7 +327,7 @@ QT_END_NAMESPACE QWidget *target = [self dragTargetHitTest:sender]; if (!target) - return [super draggingEntered:sender]; + return NSDragOperationNone; if (target->testAttribute(Qt::WA_DropSiteRegistered) == false) return NSDragOperationNone; @@ -339,7 +339,7 @@ QT_END_NAMESPACE { QWidget *target = [self dragTargetHitTest:sender]; if (!target) - return [super draggingUpdated:sender]; + return NSDragOperationNone; if (target == *currentDragTarget()) { // The drag continues to move over the widget that we have sendt @@ -363,7 +363,7 @@ QT_END_NAMESPACE { QWidget *target = [self dragTargetHitTest:sender]; if (!target) - return [super draggingExited:sender]; + return; if (*currentDragTarget()) { [reinterpret_cast<NSView *>((*currentDragTarget())->winId()) draggingExited:sender]; @@ -375,7 +375,7 @@ QT_END_NAMESPACE { QWidget *target = [self dragTargetHitTest:sender]; if (!target) - return [super performDragOperation:sender]; + return NO; BOOL dropResult = NO; if (*currentDragTarget()) { diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index fccb44d..35cea5f 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -153,6 +153,7 @@ public: int menuBeingConstructed : 1; int orientationSet : 1; int partial_keyboard : 1; + int partial_keyboardAutoTranslation : 1; int partialKeyboardOpen : 1; int handleStatusPaneResizeNotifications : 1; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type @@ -343,6 +344,7 @@ inline QS60Data::QS60Data() menuBeingConstructed(0), orientationSet(0), partial_keyboard(0), + partial_keyboardAutoTranslation(1), partialKeyboardOpen(0), handleStatusPaneResizeNotifications(1), s60ApplicationFactory(0) diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index a3173eb..65d9837 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -2827,6 +2827,12 @@ void QWidgetPrivate::deleteTLSysExtra() { // don't destroy input context here. it will be destroyed in // QWidget::destroy() destroyInputContext(); +#ifndef QT_NO_XSYNC + if (extra && extra->topextra && extra->topextra->syncUpdateCounter) { + XSyncDestroyCounter(X11->display, extra->topextra->syncUpdateCounter); + extra->topextra->syncUpdateCounter = 0; + } +#endif } void QWidgetPrivate::registerDropSite(bool on) diff --git a/src/gui/painting/qgraphicssystemex_symbian.cpp b/src/gui/painting/qgraphicssystemex_symbian.cpp index dc4dd92..4469704 100644 --- a/src/gui/painting/qgraphicssystemex_symbian.cpp +++ b/src/gui/painting/qgraphicssystemex_symbian.cpp @@ -43,7 +43,6 @@ #include "private/qwidget_p.h" #include "private/qbackingstore_p.h" #include "private/qapplication_p.h" -#include "qwidget_p.h" #include <e32property.h> diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index a4ab00a..754b16e 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6335,10 +6335,16 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QLineF line(pos.x(), pos.y(), pos.x() + width, pos.y()); - const qreal underlineOffset = fe->underlinePosition().toReal(); + qreal underlineOffset = fe->underlinePosition().toReal(); + qreal y = pos.y(); + // compensate for different rounding rule in Core Graphics paint engine, + // ideally code like this should be moved to respective engines. + if (painter->paintEngine()->type() == QPaintEngine::CoreGraphics) { + y = qCeil(y); + } // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(underlineOffset); + const qreal underlinePos = y + qCeil(underlineOffset); if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); @@ -6512,6 +6518,10 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) qreal x = p.x(); qreal y = p.y(); + bool rtl = ti.flags & QTextItem::RightToLeft; + if (rtl) + x += ti.width.toReal(); + int start = 0; int end, i; for (end = 0; end < ti.glyphs.numGlyphs; ++end) { @@ -6528,14 +6538,19 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) ti2.width += ti.glyphs.effectiveAdvance(i); } + if (rtl) + x -= ti2.width.toReal(); + d->engine->drawTextItem(QPointF(x, y), ti2); + if (!rtl) + x += ti2.width.toReal(); + // reset the high byte for all glyphs and advance to the next sub-string const int hi = which << 24; for (i = start; i < end; ++i) { glyphs.glyphs[i] = hi | glyphs.glyphs[i]; } - x += ti2.width.toReal(); // change engine start = end; @@ -6550,6 +6565,9 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) ti2.width += ti.glyphs.effectiveAdvance(i); } + if (rtl) + x -= ti2.width.toReal(); + if (d->extended) d->extended->drawTextItem(QPointF(x, y), ti2); else diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 1b84aba..bb2d701 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -146,6 +146,7 @@ const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameEleme {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter}, {SE_TableItemPressed, QS60StyleEnums::SP_QsnFrGridCenterPressed}, {SE_ListItemPressed, QS60StyleEnums::SP_QsnFrListCenterPressed}, + {SE_DialogBackground, QS60StyleEnums::SP_QsnFrPopupCenter}, }; static const int frameElementsCount = @@ -268,6 +269,9 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter, case SE_PopupBackground: drawFrame(SF_PopupBackground, painter, rect, flags | SF_PointNorth); break; + case SE_DialogBackground: + drawFrame(SF_DialogBackground, painter, rect, flags | SF_PointNorth); + break; case SE_SettingsList: drawFrame(SF_SettingsList, painter, rect, flags | SF_PointNorth); break; @@ -502,8 +506,10 @@ bool QS60StylePrivate::equalToThemePalette(qint64 cacheKey, QPalette::ColorRole { if (!m_themePalette) return false; - if (cacheKey == m_themePalette->brush(role).texture().cacheKey()) + if ((m_placeHolderTexture && (cacheKey == m_placeHolderTexture->cacheKey())) + || (cacheKey == m_themePalette->brush(role).texture().cacheKey())) return true; + return false; } @@ -2306,10 +2312,14 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) && QS60StylePrivate::equalToThemePalette(option->palette.window().texture().cacheKey(), QPalette::Window)) { const bool comboMenu = qobject_cast<const QComboBoxListView *>(widget); + const bool menu = qobject_cast<const QMenu *>(widget); // Add margin area to the background, to avoid background being cut for first and last item. const int verticalMenuAdjustment = comboMenu ? QS60StylePrivate::pixelMetric(PM_MenuVMargin) : 0; const QRect adjustedMenuRect = option->rect.adjusted(0, -verticalMenuAdjustment, 0, verticalMenuAdjustment); - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, adjustedMenuRect, flags); + if (comboMenu || menu) + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, adjustedMenuRect, flags); + else + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_DialogBackground, painter, adjustedMenuRect, flags); } else { commonStyleDraws = true; } @@ -3810,7 +3820,7 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, #if defined(Q_WS_S60) //If new custom standardIcon is missing version information, assume S60 5.3. - if (standardIcon >= SP_CustomToolBarAdd) { + if (standardIcon & QStyle::SP_CustomBase) { if (versionSupport == QSysInfo::SV_Unknown) versionSupport = QSysInfo::SV_S60_5_3; metric = PM_SmallIconSize; diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 586f1f6..10a43e2 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -541,6 +541,7 @@ public: SE_DropArea, SE_TableItemPressed, SE_ListItemPressed, + SE_DialogBackground, }; enum SkinFrameElements { @@ -560,6 +561,7 @@ public: SF_ButtonInactive, SF_TableItemPressed, SF_ListItemPressed, + SF_DialogBackground, }; enum SkinElementFlag { diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index c88d49a..67181af 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -1196,6 +1196,10 @@ void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameEleme centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu); frameId.Set(KAknsIIDQsnFrPopupSub); break; + case QS60StylePrivate::SF_DialogBackground: + centerId.Set(KAknsIIDQsnFrPopupCenter); + frameId.Set(KAknsIIDQsnFrPopup); + break; case QS60StylePrivate::SF_SettingsList: // Starting from S60_5_3, the root theme has been changed so that KAknsIIDQsnFrSetOpt is empty. // Set the theme ID to None, to avoid theme server trying to draw the empty frame. diff --git a/src/gui/text/qfont_s60.cpp b/src/gui/text/qfont_s60.cpp index a7a2547..2218617 100644 --- a/src/gui/text/qfont_s60.cpp +++ b/src/gui/text/qfont_s60.cpp @@ -55,6 +55,24 @@ Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, fontFamiliesOnFontServer, { // Therefore, we are allowed to cache the list. x->append(qt_symbian_fontFamiliesOnFontServer()); }); + +extern bool qt_symbian_isLinkedFont(const TDesC &typefaceName); // qfontdatabase_s60.cpp + +static QString classicalSymbianSystemFont() +{ + static QString font; + if (font.isEmpty()) { + static const char* const classicSymbianSystemFonts[] = { "Nokia Sans S60", "Series 60 Sans" }; + for (int i = 0; i < sizeof classicSymbianSystemFonts / sizeof classicSymbianSystemFonts[0]; ++i) { + const QString classicFont = QLatin1String(classicSymbianSystemFonts[i]); + if (fontFamiliesOnFontServer()->contains(classicFont)) { + font = classicFont; + break; + } + } + } + return font; +} #endif // QT_NO_FREETYPE QString QFont::lastResortFont() const @@ -84,6 +102,10 @@ QString QFont::lastResortFamily() const S60->screenDevice()->ReleaseFont(font); lock.relock(); + + // We must not return a Symbian Linked Font. See QTBUG-20007 + if (qt_symbian_isLinkedFont(spec.iTypeface.iName) && !classicalSymbianSystemFont().isEmpty()) + family = classicalSymbianSystemFont(); } return family; #else // QT_NO_FREETYPE @@ -103,14 +125,9 @@ QString QFont::defaultFamily() const { #ifdef QT_NO_FREETYPE switch(d->request.styleHint) { - case QFont::SansSerif: { - static const char* const preferredSansSerif[] = {"Nokia Sans S60", "Series 60 Sans"}; - for (int i = 0; i < sizeof preferredSansSerif / sizeof preferredSansSerif[0]; ++i) { - const QString sansSerif = QLatin1String(preferredSansSerif[i]); - if (fontFamiliesOnFontServer()->contains(sansSerif)) - return sansSerif; - } - } + case QFont::SansSerif: + if (!classicalSymbianSystemFont().isEmpty()) + return classicalSymbianSystemFont(); // No break. Intentional fall through. default: return lastResortFamily(); diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 1eb4242..f29c880 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -58,8 +58,22 @@ #endif // SYMBIAN_ENABLE_SPLIT_HEADERS #endif // QT_NO_FREETYPE +#ifndef SYMBIAN_VERSION_9_4 +#define SYMBIAN_LINKEDFONTS_SUPPORTED +#endif // !SYMBIAN_VERSION_9_4 + QT_BEGIN_NAMESPACE +bool qt_symbian_isLinkedFont(const TDesC &typefaceName) // Also used in qfont_s60.cpp +{ + bool isLinkedFont = false; +#ifdef SYMBIAN_LINKEDFONTS_SUPPORTED + const QString name((const QChar*)typefaceName.Ptr(), typefaceName.Length()); + isLinkedFont = name.endsWith(QLatin1String("LF")) && name == name.toUpper(); +#endif // SYMBIAN_LINKEDFONTS_SUPPORTED + return isLinkedFont; +} + QStringList qt_symbian_fontFamiliesOnFontServer() // Also used in qfont_s60.cpp { QStringList result; @@ -468,7 +482,10 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex, const QSymbianFontDatabaseExtrasImplementation *dbExtras) { TTypefaceSupport typefaceSupport; - S60->screenDevice()->TypefaceSupport(typefaceSupport, screenDeviceFontIndex); + S60->screenDevice()->TypefaceSupport(typefaceSupport, screenDeviceFontIndex); + + if (qt_symbian_isLinkedFont(typefaceSupport.iTypeface.iName)) + return false; QString familyName((const QChar*)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length()); if (qt_symbian_fontNameHasAppFontMarker(familyName)) { diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 9271f34..cff3641 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1385,6 +1385,15 @@ void QTextEngine::shape(int item) const } } +static inline void releaseCachedFontEngine(QFontEngine *fontEngine) +{ + if (fontEngine) { + fontEngine->ref.deref(); + if (fontEngine->cache_count == 0 && fontEngine->ref == 0) + delete fontEngine; + } +} + void QTextEngine::invalidate() { freeMemory(); @@ -1392,6 +1401,10 @@ void QTextEngine::invalidate() maxWidth = 0; if (specialData) specialData->resolvedFormatIndices.clear(); + + releaseCachedFontEngine(feCache.prevFontEngine); + releaseCachedFontEngine(feCache.prevScaledFontEngine); + feCache.reset(); } void QTextEngine::clearLineData() @@ -1564,19 +1577,13 @@ bool QTextEngine::isRightToLeft() const int QTextEngine::findItem(int strPos) const { itemize(); - int left = 0; - int right = layoutData->items.size()-1; - while(left <= right) { - int middle = ((right-left)/2)+left; - if (strPos > layoutData->items[middle].position) - left = middle+1; - else if(strPos < layoutData->items[middle].position) - right = middle-1; - else { - return middle; - } + + int item; + for (item = layoutData->items.size()-1; item > 0; --item) { + if (layoutData->items[item].position <= strPos) + break; } - return right; + return item; } QFixed QTextEngine::width(int from, int len) const @@ -1783,6 +1790,13 @@ QFont QTextEngine::font(const QScriptItem &si) const return font; } +QTextEngine::FontEngineCache::FontEngineCache() +{ + reset(); +} + +//we cache the previous results of this function, as calling it numerous times with the same effective +//input is common (and hard to cache at a higher level) QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent, QFixed *leading) const { QFontEngine *engine = 0; @@ -1791,28 +1805,53 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix QFont font = fnt; if (hasFormats()) { - QTextCharFormat f = format(&si); - font = f.font(); - - if (block.docHandle() && block.docHandle()->layout()) { - // Make sure we get the right dpi on printers - QPaintDevice *pdev = block.docHandle()->layout()->paintDevice(); - if (pdev) - font = QFont(font, pdev); + if (feCache.prevFontEngine && feCache.prevPosition == si.position && feCache.prevLength == length(&si) && feCache.prevScript == script) { + engine = feCache.prevFontEngine; + scaledEngine = feCache.prevScaledFontEngine; } else { - font = font.resolve(fnt); - } - engine = font.d->engineForScript(script); - QTextCharFormat::VerticalAlignment valign = f.verticalAlignment(); - if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) { - if (font.pointSize() != -1) - font.setPointSize((font.pointSize() * 2) / 3); - else - font.setPixelSize((font.pixelSize() * 2) / 3); - scaledEngine = font.d->engineForScript(script); + QTextCharFormat f = format(&si); + font = f.font(); + + if (block.docHandle() && block.docHandle()->layout()) { + // Make sure we get the right dpi on printers + QPaintDevice *pdev = block.docHandle()->layout()->paintDevice(); + if (pdev) + font = QFont(font, pdev); + } else { + font = font.resolve(fnt); + } + engine = font.d->engineForScript(script); + QTextCharFormat::VerticalAlignment valign = f.verticalAlignment(); + if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) { + if (font.pointSize() != -1) + font.setPointSize((font.pointSize() * 2) / 3); + else + font.setPixelSize((font.pixelSize() * 2) / 3); + scaledEngine = font.d->engineForScript(script); + } + feCache.prevFontEngine = engine; + if (engine) + engine->ref.ref(); + feCache.prevScaledFontEngine = scaledEngine; + if (scaledEngine) + scaledEngine->ref.ref(); + feCache.prevScript = script; + feCache.prevPosition = si.position; + feCache.prevLength = length(&si); } } else { - engine = font.d->engineForScript(script); + if (feCache.prevFontEngine && feCache.prevScript == script && feCache.prevPosition == -1) + engine = feCache.prevFontEngine; + else { + engine = font.d->engineForScript(script); + feCache.prevFontEngine = engine; + if (engine) + engine->ref.ref(); + feCache.prevScript = script; + feCache.prevPosition = -1; + feCache.prevLength = -1; + feCache.prevScaledFontEngine = 0; + } } if (si.analysis.flags == QScriptAnalysis::SmallCaps) { @@ -2744,6 +2783,7 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end, } const HB_CharAttributes *attrs = attributes(); + logClusters = this->logClusters(si); clusterLength = getClusterLength(logClusters, attrs, 0, end, glyph_pos, &clusterStart); if (clusterLength) { @@ -2778,6 +2818,22 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo : justified(false), underlineStyle(QTextCharFormat::NoUnderline), charFormat(format), num_chars(0), chars(0), logClusters(0), f(0), fontEngine(0) { + f = font; + fontEngine = f->d->engineForScript(si.analysis.script); + Q_ASSERT(fontEngine); + + initWithScriptItem(si); +} + +QTextItemInt::QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars_, int numChars, QFontEngine *fe, const QTextCharFormat &format) + : flags(0), justified(false), underlineStyle(QTextCharFormat::NoUnderline), charFormat(format), + num_chars(numChars), chars(chars_), logClusters(0), f(font), glyphs(g), fontEngine(fe) +{ +} + +// Fix up flags and underlineStyle with given info +void QTextItemInt::initWithScriptItem(const QScriptItem &si) +{ // explicitly initialize flags so that initFontAttributes can be called // multiple times on the same TextItem flags = 0; @@ -2785,13 +2841,10 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo flags |= QTextItem::RightToLeft; ascent = si.ascent; descent = si.descent; - f = font; - fontEngine = f->d->engineForScript(si.analysis.script); - Q_ASSERT(fontEngine); - if (format.hasProperty(QTextFormat::TextUnderlineStyle)) { - underlineStyle = format.underlineStyle(); - } else if (format.boolProperty(QTextFormat::FontUnderline) + if (charFormat.hasProperty(QTextFormat::TextUnderlineStyle)) { + underlineStyle = charFormat.underlineStyle(); + } else if (charFormat.boolProperty(QTextFormat::FontUnderline) || f->d->underline) { underlineStyle = QTextCharFormat::SingleUnderline; } @@ -2800,18 +2853,12 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo if (underlineStyle == QTextCharFormat::SingleUnderline) flags |= QTextItem::Underline; - if (f->d->overline || format.fontOverline()) + if (f->d->overline || charFormat.fontOverline()) flags |= QTextItem::Overline; - if (f->d->strikeOut || format.fontStrikeOut()) + if (f->d->strikeOut || charFormat.fontStrikeOut()) flags |= QTextItem::StrikeOut; } -QTextItemInt::QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars_, int numChars, QFontEngine *fe) - : flags(0), justified(false), underlineStyle(QTextCharFormat::NoUnderline), - num_chars(numChars), chars(chars_), logClusters(0), f(font), glyphs(g), fontEngine(fe) -{ -} - QTextItemInt QTextItemInt::midItem(QFontEngine *fontEngine, int firstGlyphIndex, int numGlyphs) const { QTextItemInt ti = *this; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 09610ff..c920c7b 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -311,11 +311,13 @@ public: logClusters(0), f(0), fontEngine(0) {} QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFormat &format = QTextCharFormat()); - QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars, int numChars, QFontEngine *fe); + QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars, int numChars, QFontEngine *fe, + const QTextCharFormat &format = QTextCharFormat()); /// copy the structure items, adjusting the glyphs arrays to the right subarrays. /// the width of the returned QTextItemInt is not adjusted, for speed reasons QTextItemInt midItem(QFontEngine *fontEngine, int firstGlyphIndex, int numGlyphs) const; + void initWithScriptItem(const QScriptItem &si); QFixed descent; QFixed ascent; @@ -556,6 +558,23 @@ public: mutable QScriptLineArray lines; + struct FontEngineCache { + FontEngineCache(); + mutable QFontEngine *prevFontEngine; + mutable QFontEngine *prevScaledFontEngine; + mutable int prevScript; + mutable int prevPosition; + mutable int prevLength; + inline void reset() { + prevFontEngine = 0; + prevScaledFontEngine = 0; + prevScript = -1; + prevPosition = -1; + prevLength = -1; + } + }; + mutable FontEngineCache feCache; + QString text; QFont fnt; QTextBlock block; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 4b3c9e7..d180f0e 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -76,7 +76,7 @@ static QFixed alignLine(QTextEngine *eng, const QScriptLine &line) if (align & Qt::AlignRight) x = line.width - (line.textAdvance + eng->leadingSpaceWidth(line)); else if (align & Qt::AlignHCenter) - x = (line.width - line.textAdvance)/2; + x = (line.width - (line.textAdvance))/2 - eng->leadingSpaceWidth(line); } return x; } @@ -386,6 +386,7 @@ QTextLayout::~QTextLayout() void QTextLayout::setFont(const QFont &font) { d->fnt = font; + d->feCache.reset(); } /*! @@ -518,6 +519,7 @@ void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList) } if (d->block.docHandle()) d->block.docHandle()->documentChange(d->block.position(), d->block.length()); + d->feCache.reset(); } /*! @@ -1713,6 +1715,7 @@ namespace { QFixed minimumRightBearing; QFontEngine *fontEngine; + QFontEngine *previousFontEngine; const unsigned short *logClusters; bool manualWrap; @@ -1733,12 +1736,19 @@ namespace { return glyphs.glyphs[logClusters[currentPosition - 1]]; } - inline void saveCurrentGlyph() + inline void resetPreviousGlyph() { previousGlyph = 0; + previousFontEngine = 0; + } + + inline void saveCurrentGlyph() + { + resetPreviousGlyph(); if (currentPosition > 0 && logClusters[currentPosition - 1] < glyphs.numGlyphs) { previousGlyph = currentGlyph(); // needed to calculate right bearing later + previousFontEngine = fontEngine; } } @@ -1758,8 +1768,11 @@ namespace { inline void adjustPreviousRightBearing() { - if (previousGlyph > 0) - adjustRightBearing(previousGlyph); + if (previousGlyph > 0 && previousFontEngine) { + qreal rb; + previousFontEngine->getGlyphBearings(previousGlyph, 0, &rb); + rightBearing = qMin(QFixed(), QFixed::fromReal(rb)); + } } inline void resetRightBearing() @@ -1849,7 +1862,7 @@ void QTextLine::layout_helper(int maxGlyphs) lbh.currentPosition = line.from; int end = 0; lbh.logClusters = eng->layoutData->logClustersPtr; - lbh.previousGlyph = 0; + lbh.resetPreviousGlyph(); while (newItem < eng->layoutData->items.size()) { lbh.resetRightBearing(); @@ -1867,14 +1880,14 @@ void QTextLine::layout_helper(int maxGlyphs) lbh.currentPosition = qMax(line.from, current.position); end = current.position + eng->length(item); lbh.glyphs = eng->shapedGlyphs(¤t); + QFontEngine *fontEngine = eng->fontEngine(current); + if (lbh.fontEngine != fontEngine) { + lbh.fontEngine = fontEngine; + lbh.minimumRightBearing = qMin(QFixed(), + QFixed::fromReal(fontEngine->minRightBearing())); + } } const QScriptItem ¤t = eng->layoutData->items[item]; - QFontEngine *fontEngine = eng->fontEngine(current); - if (lbh.fontEngine != fontEngine) { - lbh.fontEngine = fontEngine; - lbh.minimumRightBearing = qMin(QFixed(), - QFixed::fromReal(fontEngine->minRightBearing())); - } lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent, current.leading + current.ascent) - qMax(lbh.tmpData.ascent, @@ -2319,13 +2332,13 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR unsigned short *logClusters = eng->logClusters(&si); QGlyphLayout glyphs = eng->shapedGlyphs(&si); - QTextItemInt gf(si, &f, format); - gf.glyphs = glyphs.mid(iterator.glyphsStart, iterator.glyphsEnd - iterator.glyphsStart); - gf.chars = eng->layoutData->string.unicode() + iterator.itemStart; + QTextItemInt gf(glyphs.mid(iterator.glyphsStart, iterator.glyphsEnd - iterator.glyphsStart), + &f, eng->layoutData->string.unicode() + iterator.itemStart, + iterator.itemEnd - iterator.itemStart, eng->fontEngine(si), format); gf.logClusters = logClusters + iterator.itemStart - si.position; - gf.num_chars = iterator.itemEnd - iterator.itemStart; gf.width = iterator.itemWidth; gf.justified = line.justified; + gf.initWithScriptItem(si); Q_ASSERT(gf.fontEngine); |