From c1148ee9a60a6fae88ca09c21203e3f6c68c3c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 28 Oct 2010 14:35:43 +0200 Subject: Lighthouse: eventloop integration rework. For cocoa we really need to be able to run the cocoa eventloop [NSApplicatyion run]. Also it makes sense for openKODE without nvidia extensions. --- src/gui/kernel/qeventdispatcher_qpa.cpp | 45 ++++++++- .../kernel/qplatformeventloopintegration_qpa.cpp | 45 +++++++++ src/gui/kernel/qplatformeventloopintegration_qpa.h | 24 ++++- .../platforms/cocoa/qcocoaeventloopintegration.h | 21 ++--- .../platforms/cocoa/qcocoaeventloopintegration.mm | 104 +++++++++------------ src/plugins/platforms/cocoa/qcocoaintegration.mm | 2 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 8 +- 7 files changed, 158 insertions(+), 91 deletions(-) diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp index cb70141..31fb356 100644 --- a/src/gui/kernel/qeventdispatcher_qpa.cpp +++ b/src/gui/kernel/qeventdispatcher_qpa.cpp @@ -51,6 +51,8 @@ #include #include +#include + #include QT_BEGIN_NAMESPACE @@ -122,7 +124,8 @@ public: selectWorkerNeedsSync(true), selectWorkerHasResult(false), m_integrationInitialised(false), - m_hasIntegration(false) + m_hasIntegration(false), + m_isEventLoopIntegrationRunning(false) { } @@ -160,6 +163,20 @@ public: return m_hasIntegration; } + bool isEventLoopIntegrationRunning() const + { + return m_isEventLoopIntegrationRunning; + } + + void runEventLoopIntegration() + { + if (qApp && (qApp->thread() == QThread::currentThread())) { + m_isEventLoopIntegrationRunning = true; + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + eventLoopIntegration->startEventLoop(); + } + } + QPlatformEventLoopIntegration *eventLoopIntegration; Rendezvous *barrierBeforeBlocking; Rendezvous *barrierReturnValue; @@ -172,6 +189,7 @@ public: private: bool m_integrationInitialised; bool m_hasIntegration; + bool m_isEventLoopIntegrationRunning; }; QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent) @@ -184,6 +202,17 @@ QEventDispatcherQPA::~QEventDispatcherQPA() bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_D(QEventDispatcherQPA); + + if (d->hasIntegration()) { + if (!d->isEventLoopIntegrationRunning()) { + d->runEventLoopIntegration(); + } + if (d->threadData->quitNow) { + d->eventLoopIntegration->quitEventLoop(); + return false; + } + } + int nevents = 0; // handle gui and posted events @@ -213,8 +242,10 @@ bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags) } if (!d->interrupt) { - if (QEventDispatcherUNIX::processEvents(flags)) + if (QEventDispatcherUNIX::processEvents(flags)) { + QEventDispatcherUNIX::processEvents(flags); return true; + } } return (nevents > 0); } @@ -248,7 +279,6 @@ void QEventDispatcherQPA::flush() qApp->sendPostedEvents(); } - int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout) { @@ -266,6 +296,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ d->selectReturnMutex->unlock(); d->barrierReturnValue->checkpoint(); + d->eventLoopIntegration->setNextTimerEvent(0); return retVal; } else { d->selectWorkerNeedsSync = false; @@ -274,7 +305,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ } } d->selectReturnMutex->unlock(); - d->eventLoopIntegration->processEvents(timeoutmsec); + d->eventLoopIntegration->setNextTimerEvent(timeoutmsec); retVal = 0; //is 0 if select has not returned } else { retVal = QEventDispatcherUNIX::select(nfds, readfds, writefds, exceptfds, timeout); @@ -282,14 +313,16 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ return retVal; } + void SelectWorker::run() { + while(true) { m_retVal = 0; m_edPrivate->barrierBeforeBlocking->checkpoint(); // wait for mainthread int tmpRet = qt_safe_select(m_nfds,m_readfds,m_writefds,m_exceptfds,0); m_edPrivate->selectReturnMutex->lock(); - m_edPrivate->eventLoopIntegration->wakeup(); + m_edPrivate->eventLoopIntegration->qtNeedsToProcessEvents(); m_edPrivate->selectWorkerNeedsSync = true; m_edPrivate->selectWorkerHasResult = true; @@ -299,4 +332,6 @@ void SelectWorker::run() m_edPrivate->barrierReturnValue->checkpoint(); } } + +#include "qeventdispatcher_qpa.moc" QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp index 8bdba5e..fdb3852 100644 --- a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp +++ b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp @@ -39,3 +39,48 @@ ** ****************************************************************************/ +#include "qplatformeventloopintegration_qpa.h" + +#include + +#include + +class QPlatformEventLoopIntegrationPrivate +{ +public: + QPlatformEventLoopIntegrationPrivate(); + qint64 nextTimerEvent; +}; + +QPlatformEventLoopIntegrationPrivate::QPlatformEventLoopIntegrationPrivate() + : nextTimerEvent(0) +{ +} + +QPlatformEventLoopIntegration::QPlatformEventLoopIntegration() + : d_ptr(new QPlatformEventLoopIntegrationPrivate) + +{ +} + +QPlatformEventLoopIntegration::~QPlatformEventLoopIntegration() +{ +} + +qint64 QPlatformEventLoopIntegration::nextTimerEvent() const +{ + Q_D(const QPlatformEventLoopIntegration); + return d->nextTimerEvent; +} + + +void QPlatformEventLoopIntegration::setNextTimerEvent(qint64 nextTimerEvent) +{ + Q_D(QPlatformEventLoopIntegration); + d->nextTimerEvent = nextTimerEvent; +} + +void QPlatformEventLoopIntegration::processEvents() +{ + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); +} diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.h b/src/gui/kernel/qplatformeventloopintegration_qpa.h index a06fecf..6e0f984 100644 --- a/src/gui/kernel/qplatformeventloopintegration_qpa.h +++ b/src/gui/kernel/qplatformeventloopintegration_qpa.h @@ -43,6 +43,7 @@ #define QPLATFORMEVENTLOOPINTEGRATION_QPA_H #include +#include QT_BEGIN_HEADER @@ -50,11 +51,28 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QPlatformEventLoopIntegration +class QPlatformEventLoopIntegrationPrivate; + +class Q_GUI_EXPORT QPlatformEventLoopIntegration { + Q_DECLARE_PRIVATE(QPlatformEventLoopIntegration); public: - virtual void processEvents( qint64 msec ) = 0; - virtual void wakeup() = 0; + QPlatformEventLoopIntegration(); + virtual ~QPlatformEventLoopIntegration(); + + virtual void startEventLoop() = 0; + virtual void quitEventLoop() = 0; + virtual void qtNeedsToProcessEvents() = 0; + + qint64 nextTimerEvent() const; + void setNextTimerEvent(qint64 nextTimerEvent); + + static void processEvents(); +protected: + QScopedPointer d_ptr; +private: + Q_DISABLE_COPY(QPlatformEventLoopIntegration); + friend class QEventDispatcherQPA; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h index 8c21944..87998e3 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h @@ -46,29 +46,20 @@ #include -@interface OurApplication: NSApplication -{ - bool shouldKeepRunning; -} - -- (void) run; -- (void) processEvents: (int) msec; - -@end class QCocoaEventLoopIntegration : public QPlatformEventLoopIntegration { public: QCocoaEventLoopIntegration(); - void processEvents( qint64 msec ); - void wakeup(); + void startEventLoop(); + void quitEventLoop(); + void qtNeedsToProcessEvents(); - static int wakeupEventId; private: - OurApplication *app; + CFRunLoopSourceContext m_sourceContext; + CFRunLoopTimerContext m_timerContext; + CFRunLoopSourceRef m_source; }; - - #endif // QCOCAEVENTLOOPINTEGRATION_H diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm index b184f90..844751c 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm @@ -48,81 +48,65 @@ #include #include +#include -@implementation OurApplication - -- (void) run -{ - QCocoaAutoReleasePool pool; - [self finishLaunching]; - - shouldKeepRunning = YES; +void wakeupCallback ( void * ) { + QPlatformEventLoopIntegration::processEvents(); } -- (void) processEvents : (int) msec +void timerCallback( CFRunLoopTimerRef timer, void *info) { - QCocoaAutoReleasePool pool; - Q_UNUSED(pool); - - QElapsedTimer timer; - timer.start(); - - NSTimeInterval seconds = NSTimeInterval(msec)/1000; - id untilDate = [NSDate dateWithTimeIntervalSinceNow:seconds]; - bool continueLooping = true; - while ((timer.elapsed() < (msec-1)) && continueLooping) { - NSEvent *event = - [self nextEventMatchingMask:NSAnyEventMask - untilDate:untilDate - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if ([event type] == NSApplicationDefined - && [event subtype] == QCocoaEventLoopIntegration::wakeupEventId) { - continueLooping = false; - } else { - [self sendEvent:event]; - } - - } - [self updateWindows]; + QPlatformEventLoopIntegration::processEvents(); + QCocoaEventLoopIntegration *eventLoopIntegration = + static_cast(info); + qint64 nextTime = eventLoopIntegration->nextTimerEvent(); + CFAbsoluteTime nexttime = CFAbsoluteTimeGetCurrent(); + nexttime = nexttime + (double(nextTime)/1000); + CFRunLoopTimerSetNextFireDate(timer,nexttime); } -@end - -int QCocoaEventLoopIntegration::wakeupEventId = SHRT_MAX; - QCocoaEventLoopIntegration::QCocoaEventLoopIntegration() : QPlatformEventLoopIntegration() { - app = (OurApplication *)[OurApplication sharedApplication]; - [app run]; + [NSApplication sharedApplication]; + m_sourceContext.version = 0; + m_sourceContext.info = this; + m_sourceContext.retain = 0; + m_sourceContext.release = 0; + m_sourceContext.copyDescription = 0; + m_sourceContext.equal = 0; + m_sourceContext.hash = 0; + m_sourceContext.schedule = 0; + m_sourceContext.cancel = 0; + m_sourceContext.perform = wakeupCallback; + + m_source = CFRunLoopSourceCreate(0,0,&m_sourceContext); + CFRunLoopAddSource(CFRunLoopGetMain(),m_source,kCFRunLoopCommonModes); + + m_timerContext.version = 0; + m_timerContext.info = this; + m_timerContext.retain = 0; + m_timerContext.release = 0; + m_timerContext.copyDescription = 0; + CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent (); + CFTimeInterval interval = 30; + + CFRunLoopTimerRef m_timerSource = CFRunLoopTimerCreate(0,fireDate,interval,0,0,timerCallback,&m_timerContext); + CFRunLoopAddTimer(CFRunLoopGetMain(),m_timerSource,kCFRunLoopCommonModes); } -void QCocoaEventLoopIntegration::processEvents(qint64 msec) +void QCocoaEventLoopIntegration::startEventLoop() { - [app processEvents:msec]; + [[NSApplication sharedApplication] run]; } -void QCocoaEventLoopIntegration::wakeup() +void QCocoaEventLoopIntegration::quitEventLoop() { - QCocoaAutoReleasePool pool; - Q_UNUSED(pool); - - NSPoint p = NSMakePoint(0,0); - NSWindow *nswin = [app keyWindow]; - double timestamp = (double)(AbsoluteToDuration(UpTime())) / 1000.0; - NSEvent *event = [NSEvent - otherEventWithType:NSApplicationDefined - location:NSZeroPoint - modifierFlags:0 - timestamp: timestamp - windowNumber:[nswin windowNumber] - context:0 - subtype:QCocoaEventLoopIntegration::wakeupEventId - data1:0 - data2:0 - ]; - [app postEvent:event atStart:NO]; + [[NSApplication sharedApplication] terminate:nil]; +} +void QCocoaEventLoopIntegration::qtNeedsToProcessEvents() +{ + CFRunLoopSourceSignal(m_source); } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 79d5f51..28e894c 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -79,7 +79,7 @@ QCocoaIntegration::QCocoaIntegration() mPool = new QCocoaAutoReleasePool; //Make sure we have a nsapplication :) - [OurApplication sharedApplication]; + [NSApplication sharedApplication]; // [[OurApplication alloc] init]; NSArray *screens = [NSScreen screens]; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index f004cb8..4e233ee 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -106,11 +106,5 @@ void QCocoaWindow::windowDidResize() //jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing... NSRect rect = [[m_nsWindow contentView]frame]; QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); - if (geometry() != geo) { - widget()->setGeometry(geo); - QResizeEvent e(geo.size(), geometry().size()); - setGeometry(geo); - QApplication::sendEvent(widget(), &e); - widget()->repaint(); - } + QWindowSystemInterface::handleGeometryChange(widget(),geo); } -- cgit v0.12 From 3d86d2a8e5e3c68f9e0022e676293ddc5288c849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 27 Oct 2010 09:54:23 +0200 Subject: Disable the ./configure -qpa [platform] flag also fix what mkspec should be picked up when compiling on mac --- configure | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/configure b/configure index da48dba..08d2f54 100755 --- a/configure +++ b/configure @@ -346,7 +346,7 @@ earlyArgParse() fi ;; qpa) - CFG_EMBEDDED="$VAL" + CFG_EMBEDDED="no" if [ "$PLATFORM_QPA" != "no" ]; then if [ "$PLATFORM_QPA" = "maybe" ]; then PLATFORM_X11=no @@ -1333,7 +1333,7 @@ while [ "$#" -gt 0 ]; do fi ;; embedded-lite|qpa) - CFG_EMBEDDED="$VAL" + CFG_EMBEDDED="no" if [ "$PLATFORM_QPA" != "no" ]; then if [ "$PLATFORM_QPA" = "maybe" ]; then PLATFORM_X11=no @@ -2622,7 +2622,6 @@ fi ### help #------------------------------------------------------------------------------- [ "$PLATFORM_QWS" = "yes" -a "$CFG_EMBEDDED" = "no" ] && CFG_EMBEDDED=auto -[ "$PLATFORM_QPA" = "yes" -a "$CFG_EMBEDDED" = "no" ] && CFG_EMBEDDED=auto if [ "$CFG_EMBEDDED" != "no" ]; then case "$UNAME_SYSTEM:$UNAME_RELEASE" in Darwin:*) @@ -2705,7 +2704,7 @@ if [ -z "$PLATFORM" ]; then PLATFORM_NOTES= case "$UNAME_SYSTEM:$UNAME_RELEASE" in Darwin:*) - if [ "$PLATFORM_MAC" = "yes" ]; then + if [ "$PLATFORM_MAC" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then PLATFORM=macx-g++ # PLATFORM=macx-xcode else @@ -6957,7 +6956,6 @@ if [ "$PLATFORM_QWS" = "yes" ]; then rm -f "src/.moc/$QMAKE_OUTDIR/allmoc.cpp" # needs remaking if config changes fi if [ "$PLATFORM_QPA" = "yes" ]; then - QMAKE_OUTDIR="${QMAKE_OUTDIR}-emb-$CFG_EMBEDDED" QMAKE_CONFIG="$QMAKE_CONFIG qpa" QT_CONFIG="$QT_CONFIG qpa" rm -f "src/.moc/$QMAKE_OUTDIR/allmoc.cpp" # needs remaking if config changes -- cgit v0.12 From 6a5a894dda402b433505447f14fb7ed9eeac8a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 28 Oct 2010 12:41:31 +0200 Subject: Moving QCoreTextFontEngine with related classes into own file The declaration of QCoreTextFontEngine was ifdefed in qfontengine_p.h. So was QMacFontEngine. I have moved them into their own files (qfontengine_coretext_p.h and qfontengine_mac_p.h). --- src/gui/dialogs/qfontdialog_mac.mm | 1 + src/gui/image/qimage.cpp | 20 + src/gui/image/qimage_p.h | 1 + src/gui/painting/qpaintengine_mac.cpp | 2 + src/gui/text/qfont_mac.cpp | 1 + src/gui/text/qfontdatabase_mac.cpp | 2 + src/gui/text/qfontengine_coretext.mm | 667 +++++++++++++++++++++++++++++++++ src/gui/text/qfontengine_coretext_p.h | 136 +++++++ src/gui/text/qfontengine_mac.mm | 680 +--------------------------------- src/gui/text/qfontengine_mac_p.h | 167 +++++++++ src/gui/text/qfontengine_p.h | 210 ----------- src/gui/text/qtextengine_mac.cpp | 3 + src/gui/text/text.pri | 10 +- src/gui/util/qdesktopservices_mac.cpp | 2 + 14 files changed, 1014 insertions(+), 888 deletions(-) create mode 100644 src/gui/text/qfontengine_coretext.mm create mode 100644 src/gui/text/qfontengine_coretext_p.h create mode 100644 src/gui/text/qfontengine_mac_p.h diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 6fb363b..1b9778c 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -51,6 +51,7 @@ #include #include #include +#include #import #import diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 5829fe8..ee0ee96 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3861,6 +3861,26 @@ void qInitImageConversions() #endif } +void qGamma_correct_back_to_linear_cs(QImage *image) +{ + extern uchar qt_pow_rgb_gamma[256]; + + // gamma correct the pixels back to linear color space... + int h = image->height(); + int w = image->width(); + + for (int y=0; yscanLine(y); + for (int x=0; x #include +#include +#include #include #include #include diff --git a/src/gui/text/qfont_mac.cpp b/src/gui/text/qfont_mac.cpp index 0bc8ca2..7380f03 100644 --- a/src/gui/text/qfont_mac.cpp +++ b/src/gui/text/qfont_mac.cpp @@ -42,6 +42,7 @@ #include "qfont.h" #include "qfont_p.h" #include "qfontengine_p.h" +#include "qfontengine_mac_p.h" #include "qfontinfo.h" #include "qfontmetrics.h" #include "qpaintdevice.h" diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp index 712bdb4..93f9c84 100644 --- a/src/gui/text/qfontdatabase_mac.cpp +++ b/src/gui/text/qfontdatabase_mac.cpp @@ -45,6 +45,8 @@ #include #include #include +#include +#include QT_BEGIN_NAMESPACE diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm new file mode 100644 index 0000000..984531b --- /dev/null +++ b/src/gui/text/qfontengine_coretext.mm @@ -0,0 +1,667 @@ +#include "qfontengine_coretext_p.h" + +#include +#include + +#include + +#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + +QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning) + : QFontEngineMulti(0) +{ + this->fontDef = fontDef; + CTFontSymbolicTraits symbolicTraits = 0; + if (fontDef.weight >= QFont::Bold) + symbolicTraits |= kCTFontBoldTrait; + switch (fontDef.style) { + case QFont::StyleNormal: + break; + case QFont::StyleItalic: + case QFont::StyleOblique: + symbolicTraits |= kCTFontItalicTrait; + break; + } + + transform = CGAffineTransformIdentity; + if (fontDef.stretch != 100) { + transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); + } + + QCFType descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); + QCFType baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform); + ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits); + + // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does + // not exist for the given font. (for example italic) + if (ctfont == 0) { + ctfont = baseFont; + CFRetain(ctfont); + } + + attributeDict = CFDictionaryCreateMutable(0, 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(attributeDict, NSFontAttributeName, ctfont); + if (!kerning) { + float zero = 0.0; + QCFType noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero); + CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern); + } + + QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this); + fe->ref.ref(); + engines.append(fe); + +} + +QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti() +{ + CFRelease(ctfont); +} + +uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const +{ + for (int i = 0; i < engines.count(); ++i) { + if (CFEqual(engineAt(i)->ctfont, id)) + return i; + } + + QCoreTextFontEngineMulti *that = const_cast(this); + QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that); + fe->ref.ref(); + that->engines.append(fe); + return engines.count() - 1; +} + +bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags, + unsigned short *logClusters, const HB_CharAttributes *) const +{ + QCFType cfstring = CFStringCreateWithCharactersNoCopy(0, + reinterpret_cast(str), + len, kCFAllocatorNull); + QCFType attributedString = CFAttributedStringCreate(0, cfstring, attributeDict); + QCFType typeSetter = CTTypesetterCreateWithAttributedString(attributedString); + CFRange range = {0, 0}; + QCFType line = CTTypesetterCreateLine(typeSetter, range); + CFArrayRef array = CTLineGetGlyphRuns(line); + uint arraySize = CFArrayGetCount(array); + glyph_t *outGlyphs = glyphs->glyphs; + HB_GlyphAttributes *outAttributes = glyphs->attributes; + QFixed *outAdvances_x = glyphs->advances_x; + QFixed *outAdvances_y = glyphs->advances_y; + glyph_t *initialGlyph = outGlyphs; + + if (arraySize == 0) { + // CoreText failed to shape the text we gave it, so we assume one glyph + // per character and build a list of invalid glyphs with zero advance + *nglyphs = len; + for (int i = 0; i < len; ++i) { + outGlyphs[i] = 0; + if (logClusters) + logClusters[i] = i; + outAdvances_x[i] = QFixed(); + outAdvances_y[i] = QFixed(); + outAttributes[i].clusterStart = true; + } + return true; + } + + const bool rtl = (CTRunGetStatus(static_cast(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft); + + bool outOBounds = false; + for (uint i = 0; i < arraySize; ++i) { + CTRunRef run = static_cast(CFArrayGetValueAtIndex(array, rtl ? (arraySize - 1 - i) : i)); + CFIndex glyphCount = CTRunGetGlyphCount(run); + if (glyphCount == 0) + continue; + + Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl); + + if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) { + outOBounds = true; + } + if (!outOBounds) { + CFDictionaryRef runAttribs = CTRunGetAttributes(run); + //NSLog(@"Dictionary %@", runAttribs); + if (!runAttribs) + runAttribs = attributeDict; + CTFontRef runFont = static_cast(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); + const uint fontIndex = (fontIndexForFont(runFont) << 24); + //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); + QVarLengthArray cgglyphs(0); + const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); + if (!tmpGlyphs) { + cgglyphs.resize(glyphCount); + CTRunGetGlyphs(run, range, cgglyphs.data()); + tmpGlyphs = cgglyphs.constData(); + } + QVarLengthArray cgpoints(0); + const CGPoint *tmpPoints = CTRunGetPositionsPtr(run); + if (!tmpPoints) { + cgpoints.resize(glyphCount); + CTRunGetPositions(run, range, cgpoints.data()); + tmpPoints = cgpoints.constData(); + } + + const int rtlOffset = rtl ? (glyphCount - 1) : 0; + const int rtlSign = rtl ? -1 : 1; + + if (logClusters) { + CFRange stringRange = CTRunGetStringRange(run); + QVarLengthArray stringIndices(0); + const CFIndex *tmpIndices = CTRunGetStringIndicesPtr(run); + if (!tmpIndices) { + stringIndices.resize(glyphCount); + CTRunGetStringIndices(run, range, stringIndices.data()); + tmpIndices = stringIndices.constData(); + } + + const int firstGlyphIndex = outGlyphs - initialGlyph; + outAttributes[0].clusterStart = true; + + CFIndex k = 0; + CFIndex i = 0; + for (i = stringRange.location; + (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { + if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { + logClusters[i] = k + firstGlyphIndex; + outAttributes[k].clusterStart = true; + ++k; + } else { + logClusters[i] = k + firstGlyphIndex - 1; + } + } + // in case of a ligature at the end, fill the remaining logcluster entries + for (;i < stringRange.location + stringRange.length; i++) { + logClusters[i] = k + firstGlyphIndex - 1; + } + } + for (CFIndex i = 0; i < glyphCount - 1; ++i) { + int idx = rtlOffset + rtlSign * i; + outGlyphs[idx] = tmpGlyphs[i] | fontIndex; + outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x); + outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + outAdvances_x[idx] = outAdvances_x[idx].round(); + outAdvances_y[idx] = outAdvances_y[idx].round(); + } + } + CGSize lastGlyphAdvance; + CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1); + + outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; + outAdvances_x[rtl ? 0 : (glyphCount - 1)] = + (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(lastGlyphAdvance.width).round() + : QFixed::fromReal(lastGlyphAdvance.width); + } + outGlyphs += glyphCount; + outAttributes += glyphCount; + outAdvances_x += glyphCount; + outAdvances_y += glyphCount; + } + *nglyphs = (outGlyphs - initialGlyph); + return !outOBounds; +} + +bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, + int *nglyphs, QTextEngine::ShaperFlags flags) const +{ + *nglyphs = len; + QCFType cfstring; + + QVarLengthArray cgGlyphs(len); + CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); + + for (int i = 0; i < len; ++i) { + if (cgGlyphs[i]) { + glyphs->glyphs[i] = cgGlyphs[i]; + } else { + if (!cfstring) + cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(str), len, kCFAllocatorNull); + QCFType substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1)); + CGGlyph substituteGlyph = 0; + CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1); + if (substituteGlyph) { + const uint fontIndex = (fontIndexForFont(substituteFont) << 24); + glyphs->glyphs[i] = substituteGlyph | fontIndex; + if (!(flags & QTextEngine::GlyphIndicesOnly)) { + CGSize advance; + CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1); + glyphs->advances_x[i] = QFixed::fromReal(advance.width); + glyphs->advances_y[i] = QFixed::fromReal(advance.height); + } + } + } + } + + if (flags & QTextEngine::GlyphIndicesOnly) + return true; + + QVarLengthArray advances(len); + CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len); + + for (int i = 0; i < len; ++i) { + if (glyphs->glyphs[i] & 0xff000000) + continue; + glyphs->advances_x[i] = QFixed::fromReal(advances[i].width); + glyphs->advances_y[i] = QFixed::fromReal(advances[i].height); + } + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + for (int i = 0; i < len; ++i) { + glyphs->advances_x[i] = glyphs->advances_x[i].round(); + glyphs->advances_y[i] = glyphs->advances_y[i].round(); + } + } + + return true; +} + +void QCoreTextFontEngineMulti::recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const +{ +} +void QCoreTextFontEngineMulti::doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const +{ +} + +void QCoreTextFontEngineMulti::loadEngine(int) +{ + // Do nothing + Q_ASSERT(false); +} + + + +QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def, + QCoreTextFontEngineMulti *multiEngine) +{ + fontDef = def; + parentEngine = multiEngine; + synthesisFlags = 0; + ctfont = font; + CFRetain(ctfont); + cgFont = CTFontCopyGraphicsFont(ctfont, NULL); + CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); + if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) { + synthesisFlags |= SynthesizedBold; + } + + if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) { + synthesisFlags |= SynthesizedItalic; + } + transform = CGAffineTransformIdentity; + if (fontDef.stretch != 100) { + transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); + } + QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + if (os2Table.size() >= 10) + fsType = qFromBigEndian(reinterpret_cast(os2Table.constData() + 8)); + + QSettings appleSettings(QLatin1String("apple.com")); + QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold")); + if (appleValue.isValid()) + antialiasing_threshold = appleValue.toInt(); + else + antialiasing_threshold = -1; +} + +QCoreTextFontEngine::~QCoreTextFontEngine() +{ + CFRelease(cgFont); + CFRelease(ctfont); +} + +bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *, QTextEngine::ShaperFlags) const +{ + return false; +} + +glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) +{ + QFixed w; + bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics; + + for (int i = 0; i < glyphs.numGlyphs; ++i) { + w += round ? glyphs.effectiveAdvance(i).round() + : glyphs.effectiveAdvance(i); + } + return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0); +} +glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) +{ + glyph_metrics_t ret; + CGGlyph g = glyph; + CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, 0, 1); + ret.width = QFixed::fromReal(rect.size.width); + ret.height = QFixed::fromReal(rect.size.height); + ret.x = QFixed::fromReal(rect.origin.x); + ret.y = -QFixed::fromReal(rect.origin.y) - ret.height; + CGSize advances[1]; + CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1); + ret.xoff = QFixed::fromReal(advances[0].width); + ret.yoff = QFixed::fromReal(advances[0].height); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + ret.xoff = ret.xoff.round(); + ret.yoff = ret.yoff.round(); + } + + return ret; +} + +QFixed QCoreTextFontEngine::ascent() const +{ + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetAscent(ctfont)).round() + : QFixed::fromReal(CTFontGetAscent(ctfont)); +} +QFixed QCoreTextFontEngine::descent() const +{ + QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont)); + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + d = d.round(); + + // subtract a pixel to even out the historical +1 in QFontMetrics::height(). + // Fix in Qt 5. + return d - 1; +} +QFixed QCoreTextFontEngine::leading() const +{ + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetLeading(ctfont)).round() + : QFixed::fromReal(CTFontGetLeading(ctfont)); +} +QFixed QCoreTextFontEngine::xHeight() const +{ + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round() + : QFixed::fromReal(CTFontGetXHeight(ctfont)); +} +QFixed QCoreTextFontEngine::averageCharWidth() const +{ + // ### Need to implement properly and get the information from the OS/2 Table. + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFontEngine::averageCharWidth().round() + : QFontEngine::averageCharWidth(); +} + +qreal QCoreTextFontEngine::maxCharWidth() const +{ + // ### Max Help! + return 0; + +} +qreal QCoreTextFontEngine::minLeftBearing() const +{ + // ### Min Help! + return 0; + +} +qreal QCoreTextFontEngine::minRightBearing() const +{ + // ### Max Help! (even thought it's right) + return 0; + +} + +void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight) +{ + QVarLengthArray positions; + QVarLengthArray glyphs; + QTransform matrix; + matrix.translate(x, y); + getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + if (glyphs.size() == 0) + return; + + CGContextSetFontSize(ctx, fontDef.pixelSize); + + CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); + + CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight); + + CGAffineTransformConcat(cgMatrix, oldTextMatrix); + + if (synthesisFlags & QFontEngine::SynthesizedItalic) + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); + + cgMatrix = CGAffineTransformConcat(cgMatrix, transform); + + CGContextSetTextMatrix(ctx, cgMatrix); + + CGContextSetTextDrawingMode(ctx, kCGTextFill); + + + QVarLengthArray advances(glyphs.size()); + QVarLengthArray cgGlyphs(glyphs.size()); + + for (int i = 0; i < glyphs.size() - 1; ++i) { + advances[i].width = (positions[i + 1].x - positions[i].x).toReal(); + advances[i].height = (positions[i + 1].y - positions[i].y).toReal(); + cgGlyphs[i] = glyphs[i]; + } + advances[glyphs.size() - 1].width = 0; + advances[glyphs.size() - 1].height = 0; + cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1]; + + CGContextSetFont(ctx, cgFont); + //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont)); + + CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal()); + + CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); + + if (synthesisFlags & QFontEngine::SynthesizedBold) { + CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(), + positions[0].y.toReal()); + + CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); + } + + CGContextSetTextMatrix(ctx, oldTextMatrix); +} + +struct ConvertPathInfo +{ + ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos) : path(newPath), pos(newPos) {} + QPainterPath *path; + QPointF pos; +}; + +static void convertCGPathToQPainterPath(void *info, const CGPathElement *element) +{ + ConvertPathInfo *myInfo = static_cast(info); + switch(element->type) { + case kCGPathElementMoveToPoint: + myInfo->path->moveTo(element->points[0].x + myInfo->pos.x(), + element->points[0].y + myInfo->pos.y()); + break; + case kCGPathElementAddLineToPoint: + myInfo->path->lineTo(element->points[0].x + myInfo->pos.x(), + element->points[0].y + myInfo->pos.y()); + break; + case kCGPathElementAddQuadCurveToPoint: + myInfo->path->quadTo(element->points[0].x + myInfo->pos.x(), + element->points[0].y + myInfo->pos.y(), + element->points[1].x + myInfo->pos.x(), + element->points[1].y + myInfo->pos.y()); + break; + case kCGPathElementAddCurveToPoint: + myInfo->path->cubicTo(element->points[0].x + myInfo->pos.x(), + element->points[0].y + myInfo->pos.y(), + element->points[1].x + myInfo->pos.x(), + element->points[1].y + myInfo->pos.y(), + element->points[2].x + myInfo->pos.x(), + element->points[2].y + myInfo->pos.y()); + break; + case kCGPathElementCloseSubpath: + myInfo->path->closeSubpath(); + break; + default: + qDebug() << "Unhandled path transform type: " << element->type; + } + +} + +void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs, + QPainterPath *path, QTextItem::RenderFlags) +{ + + CGAffineTransform cgMatrix = CGAffineTransformIdentity; + cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); + + if (synthesisFlags & QFontEngine::SynthesizedItalic) + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); + + + for (int i = 0; i < nGlyphs; ++i) { + QCFType cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix); + ConvertPathInfo info(path, positions[i].toPointF()); + CGPathApply(cgpath, &info, convertCGPathToQPainterPath); + } +} + +QFont QCoreTextFontEngine::createExplicitFont() const +{ + QString familyName = QCFString::toQString(CTFontCopyFamilyName(ctfont)); + return createExplicitFontWithName(familyName); +} + +QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa) +{ + const glyph_metrics_t br = boundingBox(glyph); + QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32); + im.fill(0); + + CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + uint cgflags = kCGImageAlphaNoneSkipFirst; +#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version + cgflags |= kCGBitmapByteOrder32Host; +#endif + CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), + 8, im.bytesPerLine(), colorspace, + cgflags); + CGContextSetFontSize(ctx, fontDef.pixelSize); + CGContextSetShouldAntialias(ctx, aa || + (fontDef.pointSize > antialiasing_threshold + && !(fontDef.styleStrategy & QFont::NoAntialias))); + CGContextSetShouldSmoothFonts(ctx, aa); + CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); + CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); + + CGAffineTransformConcat(cgMatrix, oldTextMatrix); + + if (synthesisFlags & QFontEngine::SynthesizedItalic) + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0)); + + cgMatrix = CGAffineTransformConcat(cgMatrix, transform); + + CGContextSetTextMatrix(ctx, cgMatrix); + CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); + CGContextSetTextDrawingMode(ctx, kCGTextFill); + + CGContextSetFont(ctx, cgFont); + + qreal pos_x = -br.x.toReal() + subPixelPosition.toReal(); + qreal pos_y = im.height()+br.y.toReal(); + CGContextSetTextPosition(ctx, pos_x, pos_y); + + CGSize advance; + advance.width = 0; + advance.height = 0; + CGGlyph cgGlyph = glyph; + CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); + + if (synthesisFlags & QFontEngine::SynthesizedBold) { + CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); + CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); + } + + CGContextRelease(ctx); + + return im; +} + +QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) +{ + QImage im = imageForGlyph(glyph, QFixed(), 0, false); + + QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); + QVector colors(256); + for (int i=0; i<256; ++i) + colors[i] = qRgba(0, 0, 0, i); + indexed.setColorTable(colors); + + for (int y=0; y= QTransform::TxScale) + return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, margin, x); + + QImage im = imageForGlyph(glyph, subPixelPosition, margin, true); + qGamma_correct_back_to_linear_cs(&im); + return im; +} + +void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const +{ + Q_ASSERT(false); + Q_UNUSED(numGlyphs); + Q_UNUSED(glyphs); + Q_UNUSED(flags); +} + +QFontEngine::FaceId QCoreTextFontEngine::faceId() const +{ + return QFontEngine::FaceId(); +} + +bool QCoreTextFontEngine::canRender(const QChar *string, int len) +{ + QCFType retFont = CTFontCreateForString(ctfont, + QCFType(CFStringCreateWithCharactersNoCopy(0, + reinterpret_cast(string), + len, kCFAllocatorNull)), + CFRangeMake(0, len)); + return retFont != 0; + return false; +} + + bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const + { + QCFType table = CTFontCopyTable(ctfont, tag, 0); + if (!table || !length) + return false; + CFIndex tableLength = CFDataGetLength(table); + int availableLength = *length; + *length = tableLength; + if (buffer) { + if (tableLength > availableLength) + return false; + CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer); + } + return true; + } + +void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *) +{ + // ### +} + +#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h new file mode 100644 index 0000000..d86c153 --- /dev/null +++ b/src/gui/text/qfontengine_coretext_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFONTENGINE_CORETEXT_P_H +#define QFONTENGINE_CORETEXT_P_H + +#include + +#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + +class QCoreTextFontEngineMulti; +class QCoreTextFontEngine : public QFontEngine +{ +public: + QCoreTextFontEngine(CTFontRef font, const QFontDef &def, + QCoreTextFontEngineMulti *multiEngine = 0); + ~QCoreTextFontEngine(); + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; + virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; + + virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); + virtual glyph_metrics_t boundingBox(glyph_t glyph); + + virtual QFixed ascent() const; + virtual QFixed descent() const; + virtual QFixed leading() const; + virtual QFixed xHeight() const; + virtual qreal maxCharWidth() const; + virtual QFixed averageCharWidth() const; + + virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, + QPainterPath *path, QTextItem::RenderFlags); + + virtual const char *name() const { return "QCoreTextFontEngine"; } + + virtual bool canRender(const QChar *string, int len); + + virtual int synthesized() const { return synthesisFlags; } + virtual bool supportsSubPixelPositions() const { return true; } + + virtual Type type() const { return QFontEngine::Mac; } + + void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); + + virtual FaceId faceId() const; + virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; + virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); + virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); + virtual qreal minRightBearing() const; + virtual qreal minLeftBearing() const; + virtual QFont createExplicitFont() const; + +private: + QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful); + CTFontRef ctfont; + CGFontRef cgFont; + QCoreTextFontEngineMulti *parentEngine; + int synthesisFlags; + CGAffineTransform transform; + friend class QCoreTextFontEngineMulti; + int antialiasing_threshold; +}; + +class QCoreTextFontEngineMulti : public QFontEngineMulti +{ +public: + QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning); + ~QCoreTextFontEngineMulti(); + + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, + QTextEngine::ShaperFlags flags) const; + bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, + QTextEngine::ShaperFlags flags, + unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; + + + virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; + virtual void doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; + + virtual const char *name() const { return "CoreText"; } +protected: + virtual void loadEngine(int at); + +private: + inline const QCoreTextFontEngine *engineAt(int i) const + { return static_cast(engines.at(i)); } + + uint fontIndexForFont(CTFontRef id) const; + CTFontRef ctfont; + mutable QCFType attributeDict; + CGAffineTransform transform; + friend class QFontDialogPrivate; +}; + +#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + +#endif // QFONTENGINE_CORETEXT_P_H diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index ebc1f6d..8801181 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include "qfontengine_mac_p.h" + #include #include #include @@ -53,6 +55,7 @@ #include #include #include +#include #include #include @@ -118,681 +121,6 @@ OSStatus QMacFontPath::closePath(void *data) return noErr; } - - -void qmacfontengine_gamma_correct(QImage *image) -{ - extern uchar qt_pow_rgb_gamma[256]; - - // gamma correct the pixels back to linear color space... - int h = image->height(); - int w = image->width(); - - for (int y=0; yscanLine(y); - for (int x=0; x= MAC_OS_X_VERSION_10_5 -QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning) - : QFontEngineMulti(0) -{ - this->fontDef = fontDef; - CTFontSymbolicTraits symbolicTraits = 0; - if (fontDef.weight >= QFont::Bold) - symbolicTraits |= kCTFontBoldTrait; - switch (fontDef.style) { - case QFont::StyleNormal: - break; - case QFont::StyleItalic: - case QFont::StyleOblique: - symbolicTraits |= kCTFontItalicTrait; - break; - } - - transform = CGAffineTransformIdentity; - if (fontDef.stretch != 100) { - transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); - } - - QCFType descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); - QCFType baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform); - ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits); - - // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does - // not exist for the given font. (for example italic) - if (ctfont == 0) { - ctfont = baseFont; - CFRetain(ctfont); - } - - attributeDict = CFDictionaryCreateMutable(0, 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(attributeDict, NSFontAttributeName, ctfont); - if (!kerning) { - float zero = 0.0; - QCFType noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero); - CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern); - } - - QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this); - fe->ref.ref(); - engines.append(fe); - -} - -QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti() -{ - CFRelease(ctfont); -} - -uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const -{ - for (int i = 0; i < engines.count(); ++i) { - if (CFEqual(engineAt(i)->ctfont, id)) - return i; - } - - QCoreTextFontEngineMulti *that = const_cast(this); - QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that); - fe->ref.ref(); - that->engines.append(fe); - return engines.count() - 1; -} - -bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags, - unsigned short *logClusters, const HB_CharAttributes *) const -{ - QCFType cfstring = CFStringCreateWithCharactersNoCopy(0, - reinterpret_cast(str), - len, kCFAllocatorNull); - QCFType attributedString = CFAttributedStringCreate(0, cfstring, attributeDict); - QCFType typeSetter = CTTypesetterCreateWithAttributedString(attributedString); - CFRange range = {0, 0}; - QCFType line = CTTypesetterCreateLine(typeSetter, range); - CFArrayRef array = CTLineGetGlyphRuns(line); - uint arraySize = CFArrayGetCount(array); - glyph_t *outGlyphs = glyphs->glyphs; - HB_GlyphAttributes *outAttributes = glyphs->attributes; - QFixed *outAdvances_x = glyphs->advances_x; - QFixed *outAdvances_y = glyphs->advances_y; - glyph_t *initialGlyph = outGlyphs; - - if (arraySize == 0) { - // CoreText failed to shape the text we gave it, so we assume one glyph - // per character and build a list of invalid glyphs with zero advance - *nglyphs = len; - for (int i = 0; i < len; ++i) { - outGlyphs[i] = 0; - if (logClusters) - logClusters[i] = i; - outAdvances_x[i] = QFixed(); - outAdvances_y[i] = QFixed(); - outAttributes[i].clusterStart = true; - } - return true; - } - - const bool rtl = (CTRunGetStatus(static_cast(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft); - - bool outOBounds = false; - for (uint i = 0; i < arraySize; ++i) { - CTRunRef run = static_cast(CFArrayGetValueAtIndex(array, rtl ? (arraySize - 1 - i) : i)); - CFIndex glyphCount = CTRunGetGlyphCount(run); - if (glyphCount == 0) - continue; - - Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl); - - if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) { - outOBounds = true; - } - if (!outOBounds) { - CFDictionaryRef runAttribs = CTRunGetAttributes(run); - //NSLog(@"Dictionary %@", runAttribs); - if (!runAttribs) - runAttribs = attributeDict; - CTFontRef runFont = static_cast(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); - const uint fontIndex = (fontIndexForFont(runFont) << 24); - //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); - QVarLengthArray cgglyphs(0); - const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); - if (!tmpGlyphs) { - cgglyphs.resize(glyphCount); - CTRunGetGlyphs(run, range, cgglyphs.data()); - tmpGlyphs = cgglyphs.constData(); - } - QVarLengthArray cgpoints(0); - const CGPoint *tmpPoints = CTRunGetPositionsPtr(run); - if (!tmpPoints) { - cgpoints.resize(glyphCount); - CTRunGetPositions(run, range, cgpoints.data()); - tmpPoints = cgpoints.constData(); - } - - const int rtlOffset = rtl ? (glyphCount - 1) : 0; - const int rtlSign = rtl ? -1 : 1; - - if (logClusters) { - CFRange stringRange = CTRunGetStringRange(run); - QVarLengthArray stringIndices(0); - const CFIndex *tmpIndices = CTRunGetStringIndicesPtr(run); - if (!tmpIndices) { - stringIndices.resize(glyphCount); - CTRunGetStringIndices(run, range, stringIndices.data()); - tmpIndices = stringIndices.constData(); - } - - const int firstGlyphIndex = outGlyphs - initialGlyph; - outAttributes[0].clusterStart = true; - - CFIndex k = 0; - CFIndex i = 0; - for (i = stringRange.location; - (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { - if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { - logClusters[i] = k + firstGlyphIndex; - outAttributes[k].clusterStart = true; - ++k; - } else { - logClusters[i] = k + firstGlyphIndex - 1; - } - } - // in case of a ligature at the end, fill the remaining logcluster entries - for (;i < stringRange.location + stringRange.length; i++) { - logClusters[i] = k + firstGlyphIndex - 1; - } - } - for (CFIndex i = 0; i < glyphCount - 1; ++i) { - int idx = rtlOffset + rtlSign * i; - outGlyphs[idx] = tmpGlyphs[i] | fontIndex; - outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x); - outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y); - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - outAdvances_x[idx] = outAdvances_x[idx].round(); - outAdvances_y[idx] = outAdvances_y[idx].round(); - } - } - CGSize lastGlyphAdvance; - CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1); - - outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; - outAdvances_x[rtl ? 0 : (glyphCount - 1)] = - (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(lastGlyphAdvance.width).round() - : QFixed::fromReal(lastGlyphAdvance.width); - } - outGlyphs += glyphCount; - outAttributes += glyphCount; - outAdvances_x += glyphCount; - outAdvances_y += glyphCount; - } - *nglyphs = (outGlyphs - initialGlyph); - return !outOBounds; -} - -bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, - int *nglyphs, QTextEngine::ShaperFlags flags) const -{ - *nglyphs = len; - QCFType cfstring; - - QVarLengthArray cgGlyphs(len); - CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); - - for (int i = 0; i < len; ++i) { - if (cgGlyphs[i]) { - glyphs->glyphs[i] = cgGlyphs[i]; - } else { - if (!cfstring) - cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(str), len, kCFAllocatorNull); - QCFType substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1)); - CGGlyph substituteGlyph = 0; - CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1); - if (substituteGlyph) { - const uint fontIndex = (fontIndexForFont(substituteFont) << 24); - glyphs->glyphs[i] = substituteGlyph | fontIndex; - if (!(flags & QTextEngine::GlyphIndicesOnly)) { - CGSize advance; - CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1); - glyphs->advances_x[i] = QFixed::fromReal(advance.width); - glyphs->advances_y[i] = QFixed::fromReal(advance.height); - } - } - } - } - - if (flags & QTextEngine::GlyphIndicesOnly) - return true; - - QVarLengthArray advances(len); - CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len); - - for (int i = 0; i < len; ++i) { - if (glyphs->glyphs[i] & 0xff000000) - continue; - glyphs->advances_x[i] = QFixed::fromReal(advances[i].width); - glyphs->advances_y[i] = QFixed::fromReal(advances[i].height); - } - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - for (int i = 0; i < len; ++i) { - glyphs->advances_x[i] = glyphs->advances_x[i].round(); - glyphs->advances_y[i] = glyphs->advances_y[i].round(); - } - } - - return true; -} - -void QCoreTextFontEngineMulti::recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const -{ -} -void QCoreTextFontEngineMulti::doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const -{ -} - -void QCoreTextFontEngineMulti::loadEngine(int) -{ - // Do nothing - Q_ASSERT(false); -} - - - -QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def, - QCoreTextFontEngineMulti *multiEngine) -{ - fontDef = def; - parentEngine = multiEngine; - synthesisFlags = 0; - ctfont = font; - CFRetain(ctfont); - cgFont = CTFontCopyGraphicsFont(ctfont, NULL); - CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); - if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) { - synthesisFlags |= SynthesizedBold; - } - - if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) { - synthesisFlags |= SynthesizedItalic; - } - transform = CGAffineTransformIdentity; - if (fontDef.stretch != 100) { - transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); - } - QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); - if (os2Table.size() >= 10) - fsType = qFromBigEndian(reinterpret_cast(os2Table.constData() + 8)); -} - -QCoreTextFontEngine::~QCoreTextFontEngine() -{ - CFRelease(cgFont); - CFRelease(ctfont); -} - -bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *, QTextEngine::ShaperFlags) const -{ - return false; -} - -glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) -{ - QFixed w; - bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics; - - for (int i = 0; i < glyphs.numGlyphs; ++i) { - w += round ? glyphs.effectiveAdvance(i).round() - : glyphs.effectiveAdvance(i); - } - return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0); -} -glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) -{ - glyph_metrics_t ret; - CGGlyph g = glyph; - CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, 0, 1); - ret.width = QFixed::fromReal(rect.size.width); - ret.height = QFixed::fromReal(rect.size.height); - ret.x = QFixed::fromReal(rect.origin.x); - ret.y = -QFixed::fromReal(rect.origin.y) - ret.height; - CGSize advances[1]; - CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1); - ret.xoff = QFixed::fromReal(advances[0].width); - ret.yoff = QFixed::fromReal(advances[0].height); - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - ret.xoff = ret.xoff.round(); - ret.yoff = ret.yoff.round(); - } - - return ret; -} - -QFixed QCoreTextFontEngine::ascent() const -{ - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetAscent(ctfont)).round() - : QFixed::fromReal(CTFontGetAscent(ctfont)); -} -QFixed QCoreTextFontEngine::descent() const -{ - QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont)); - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - d = d.round(); - - // subtract a pixel to even out the historical +1 in QFontMetrics::height(). - // Fix in Qt 5. - return d - 1; -} -QFixed QCoreTextFontEngine::leading() const -{ - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetLeading(ctfont)).round() - : QFixed::fromReal(CTFontGetLeading(ctfont)); -} -QFixed QCoreTextFontEngine::xHeight() const -{ - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round() - : QFixed::fromReal(CTFontGetXHeight(ctfont)); -} -QFixed QCoreTextFontEngine::averageCharWidth() const -{ - // ### Need to implement properly and get the information from the OS/2 Table. - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? QFontEngine::averageCharWidth().round() - : QFontEngine::averageCharWidth(); -} - -qreal QCoreTextFontEngine::maxCharWidth() const -{ - // ### Max Help! - return 0; - -} -qreal QCoreTextFontEngine::minLeftBearing() const -{ - // ### Min Help! - return 0; - -} -qreal QCoreTextFontEngine::minRightBearing() const -{ - // ### Max Help! (even thought it's right) - return 0; - -} - -void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight) -{ - QVarLengthArray positions; - QVarLengthArray glyphs; - QTransform matrix; - matrix.translate(x, y); - getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); - if (glyphs.size() == 0) - return; - - CGContextSetFontSize(ctx, fontDef.pixelSize); - - CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); - - CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight); - - CGAffineTransformConcat(cgMatrix, oldTextMatrix); - - if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); - - cgMatrix = CGAffineTransformConcat(cgMatrix, transform); - - CGContextSetTextMatrix(ctx, cgMatrix); - - CGContextSetTextDrawingMode(ctx, kCGTextFill); - - - QVarLengthArray advances(glyphs.size()); - QVarLengthArray cgGlyphs(glyphs.size()); - - for (int i = 0; i < glyphs.size() - 1; ++i) { - advances[i].width = (positions[i + 1].x - positions[i].x).toReal(); - advances[i].height = (positions[i + 1].y - positions[i].y).toReal(); - cgGlyphs[i] = glyphs[i]; - } - advances[glyphs.size() - 1].width = 0; - advances[glyphs.size() - 1].height = 0; - cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1]; - - CGContextSetFont(ctx, cgFont); - //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont)); - - CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal()); - - CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); - - if (synthesisFlags & QFontEngine::SynthesizedBold) { - CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(), - positions[0].y.toReal()); - - CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); - } - - CGContextSetTextMatrix(ctx, oldTextMatrix); -} - -struct ConvertPathInfo -{ - ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos) : path(newPath), pos(newPos) {} - QPainterPath *path; - QPointF pos; -}; - -static void convertCGPathToQPainterPath(void *info, const CGPathElement *element) -{ - ConvertPathInfo *myInfo = static_cast(info); - switch(element->type) { - case kCGPathElementMoveToPoint: - myInfo->path->moveTo(element->points[0].x + myInfo->pos.x(), - element->points[0].y + myInfo->pos.y()); - break; - case kCGPathElementAddLineToPoint: - myInfo->path->lineTo(element->points[0].x + myInfo->pos.x(), - element->points[0].y + myInfo->pos.y()); - break; - case kCGPathElementAddQuadCurveToPoint: - myInfo->path->quadTo(element->points[0].x + myInfo->pos.x(), - element->points[0].y + myInfo->pos.y(), - element->points[1].x + myInfo->pos.x(), - element->points[1].y + myInfo->pos.y()); - break; - case kCGPathElementAddCurveToPoint: - myInfo->path->cubicTo(element->points[0].x + myInfo->pos.x(), - element->points[0].y + myInfo->pos.y(), - element->points[1].x + myInfo->pos.x(), - element->points[1].y + myInfo->pos.y(), - element->points[2].x + myInfo->pos.x(), - element->points[2].y + myInfo->pos.y()); - break; - case kCGPathElementCloseSubpath: - myInfo->path->closeSubpath(); - break; - default: - qDebug() << "Unhandled path transform type: " << element->type; - } - -} - -void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs, - QPainterPath *path, QTextItem::RenderFlags) -{ - - CGAffineTransform cgMatrix = CGAffineTransformIdentity; - cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); - - if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); - - - for (int i = 0; i < nGlyphs; ++i) { - QCFType cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix); - ConvertPathInfo info(path, positions[i].toPointF()); - CGPathApply(cgpath, &info, convertCGPathToQPainterPath); - } -} - -QFont QCoreTextFontEngine::createExplicitFont() const -{ - QString familyName = QCFString::toQString(CTFontCopyFamilyName(ctfont)); - return createExplicitFontWithName(familyName); -} - -QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa) -{ - const glyph_metrics_t br = boundingBox(glyph); - QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32); - im.fill(0); - - CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); - uint cgflags = kCGImageAlphaNoneSkipFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - cgflags |= kCGBitmapByteOrder32Host; -#endif - CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), - 8, im.bytesPerLine(), colorspace, - cgflags); - CGContextSetFontSize(ctx, fontDef.pixelSize); - CGContextSetShouldAntialias(ctx, aa || - (fontDef.pointSize > qt_antialiasing_threshold - && !(fontDef.styleStrategy & QFont::NoAntialias))); - CGContextSetShouldSmoothFonts(ctx, aa); - CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); - CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); - - CGAffineTransformConcat(cgMatrix, oldTextMatrix); - - if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0)); - - cgMatrix = CGAffineTransformConcat(cgMatrix, transform); - - CGContextSetTextMatrix(ctx, cgMatrix); - CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); - CGContextSetTextDrawingMode(ctx, kCGTextFill); - - CGContextSetFont(ctx, cgFont); - - qreal pos_x = -br.x.toReal() + subPixelPosition.toReal(); - qreal pos_y = im.height()+br.y.toReal(); - CGContextSetTextPosition(ctx, pos_x, pos_y); - - CGSize advance; - advance.width = 0; - advance.height = 0; - CGGlyph cgGlyph = glyph; - CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); - - if (synthesisFlags & QFontEngine::SynthesizedBold) { - CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); - CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); - } - - CGContextRelease(ctx); - - return im; -} - -QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) -{ - QImage im = imageForGlyph(glyph, QFixed(), 0, false); - - QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); - QVector colors(256); - for (int i=0; i<256; ++i) - colors[i] = qRgba(0, 0, 0, i); - indexed.setColorTable(colors); - - for (int y=0; y= QTransform::TxScale) - return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, margin, x); - - QImage im = imageForGlyph(glyph, subPixelPosition, margin, true); - qmacfontengine_gamma_correct(&im); - return im; -} - -void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const -{ - Q_ASSERT(false); - Q_UNUSED(numGlyphs); - Q_UNUSED(glyphs); - Q_UNUSED(flags); -} - -QFontEngine::FaceId QCoreTextFontEngine::faceId() const -{ - return QFontEngine::FaceId(); -} - -bool QCoreTextFontEngine::canRender(const QChar *string, int len) -{ - QCFType retFont = CTFontCreateForString(ctfont, - QCFType(CFStringCreateWithCharactersNoCopy(0, - reinterpret_cast(string), - len, kCFAllocatorNull)), - CFRangeMake(0, len)); - return retFont != 0; - return false; -} - - bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const - { - QCFType table = CTFontCopyTable(ctfont, tag, 0); - if (!table || !length) - return false; - CFIndex tableLength = CFDataGetLength(table); - int availableLength = *length; - *length = tableLength; - if (buffer) { - if (tableLength > availableLength) - return false; - CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer); - } - return true; - } - -void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *) -{ - // ### -} - -#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - #ifndef QT_MAC_USE_COCOA QFontEngineMacMulti::QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning) : QFontEngineMulti(0) @@ -1708,7 +1036,7 @@ QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co im = im.transformed(t); } - qmacfontengine_gamma_correct(&im); + qGamma_correct_back_to_linear_cs(&im); return im; } diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h new file mode 100644 index 0000000..5577c76 --- /dev/null +++ b/src/gui/text/qfontengine_mac_p.h @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFONTENGINE_MAC_P_H +#define QFONTENGINE_MAC_P_H + +#include + +#ifndef QT_MAC_USE_COCOA +class QFontEngineMacMulti; +class QFontEngineMac : public QFontEngine +{ + friend class QFontEngineMacMulti; +public: + QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine = 0); + virtual ~QFontEngineMac(); + + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *numGlyphs, QTextEngine::ShaperFlags flags) const; + virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; + + virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); + virtual glyph_metrics_t boundingBox(glyph_t glyph); + + virtual QFixed ascent() const; + virtual QFixed descent() const; + virtual QFixed leading() const; + virtual QFixed xHeight() const; + virtual qreal maxCharWidth() const; + virtual QFixed averageCharWidth() const; + + virtual QFont createExplicitFont() const; + + virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, + QPainterPath *path, QTextItem::RenderFlags); + + virtual const char *name() const { return "QFontEngineMac"; } + + virtual bool canRender(const QChar *string, int len); + + virtual int synthesized() const { return synthesisFlags; } + + virtual Type type() const { return QFontEngine::Mac; } + + void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); + + virtual FaceId faceId() const; + virtual QByteArray getSfntTable(uint tag) const; + virtual Properties properties() const; + virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); + virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); + +private: + QImage imageForGlyph(glyph_t glyph, int margin, bool colorful); + + ATSUFontID fontID; + QCFType cgFont; + ATSUStyle style; + int synthesisFlags; + mutable QGlyphLayout kashidaGlyph; + QFontEngineMacMulti *multiEngine; + mutable const unsigned char *cmap; + mutable bool symbolCMap; + mutable QByteArray cmapTable; + CGAffineTransform transform; + QFixed m_ascent; + QFixed m_descent; + QFixed m_leading; + qreal m_maxCharWidth; + QFixed m_xHeight; + QFixed m_averageCharWidth; +}; + +class QFontEngineMacMulti : public QFontEngineMulti +{ + friend class QFontEngineMac; +public: + // internal + struct ShaperItem + { + inline ShaperItem() : string(0), from(0), length(0), + log_clusters(0), charAttributes(0) {} + + const QChar *string; + int from; + int length; + QGlyphLayout glyphs; + unsigned short *log_clusters; + const HB_CharAttributes *charAttributes; + QTextEngine::ShaperFlags flags; + }; + + QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning); + virtual ~QFontEngineMacMulti(); + + virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; + bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, + unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; + + virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; + virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const; + + virtual const char *name() const { return "ATSUI"; } + + virtual bool canRender(const QChar *string, int len); + + inline ATSUFontID macFontID() const { return fontID; } + +protected: + virtual void loadEngine(int at); + +private: + inline const QFontEngineMac *engineAt(int i) const + { return static_cast(engines.at(i)); } + + bool stringToCMapInternal(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, ShaperItem *item) const; + + int fontIndexForFontID(ATSUFontID id) const; + + ATSUFontID fontID; + uint kerning : 1; + + mutable ATSUTextLayout textLayout; + mutable ATSUStyle style; + CGAffineTransform transform; +}; +#endif //!QT_MAC_USE_COCOA + +#endif // QFONTENGINE_MAC_P_H diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 6d6daaa..c584ba1 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -431,216 +431,6 @@ protected: QVector engines; }; -#if defined(Q_WS_MAC) - -struct QCharAttributes; -class QFontEngineMacMulti; -# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 -class QCoreTextFontEngineMulti; -class QCoreTextFontEngine : public QFontEngine -{ -public: - QCoreTextFontEngine(CTFontRef font, const QFontDef &def, - QCoreTextFontEngineMulti *multiEngine = 0); - ~QCoreTextFontEngine(); - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; - virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; - - virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); - virtual glyph_metrics_t boundingBox(glyph_t glyph); - - virtual QFixed ascent() const; - virtual QFixed descent() const; - virtual QFixed leading() const; - virtual QFixed xHeight() const; - virtual qreal maxCharWidth() const; - virtual QFixed averageCharWidth() const; - - virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, - QPainterPath *path, QTextItem::RenderFlags); - - virtual const char *name() const { return "QCoreTextFontEngine"; } - - virtual bool canRender(const QChar *string, int len); - - virtual int synthesized() const { return synthesisFlags; } - virtual bool supportsSubPixelPositions() const { return true; } - - virtual Type type() const { return QFontEngine::Mac; } - - void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); - - virtual FaceId faceId() const; - virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; - virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t); - virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); - virtual qreal minRightBearing() const; - virtual qreal minLeftBearing() const; - virtual QFont createExplicitFont() const; - -private: - QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful); - CTFontRef ctfont; - CGFontRef cgFont; - QCoreTextFontEngineMulti *parentEngine; - int synthesisFlags; - CGAffineTransform transform; - friend class QCoreTextFontEngineMulti; -}; - -class QCoreTextFontEngineMulti : public QFontEngineMulti -{ -public: - QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning); - ~QCoreTextFontEngineMulti(); - - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, - QTextEngine::ShaperFlags flags) const; - bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, - QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; - - - virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; - virtual void doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const; - - virtual const char *name() const { return "CoreText"; } -protected: - virtual void loadEngine(int at); - -private: - inline const QCoreTextFontEngine *engineAt(int i) const - { return static_cast(engines.at(i)); } - - uint fontIndexForFont(CTFontRef id) const; - CTFontRef ctfont; - mutable QCFType attributeDict; - CGAffineTransform transform; - friend class QFontDialogPrivate; -}; -# endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - -#ifndef QT_MAC_USE_COCOA -class QFontEngineMac : public QFontEngine -{ - friend class QFontEngineMacMulti; -public: - QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFontDef &def, QFontEngineMacMulti *multiEngine = 0); - virtual ~QFontEngineMac(); - - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *numGlyphs, QTextEngine::ShaperFlags flags) const; - virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; - - virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); - virtual glyph_metrics_t boundingBox(glyph_t glyph); - - virtual QFixed ascent() const; - virtual QFixed descent() const; - virtual QFixed leading() const; - virtual QFixed xHeight() const; - virtual qreal maxCharWidth() const; - virtual QFixed averageCharWidth() const; - - virtual QFont createExplicitFont() const; - - virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, - QPainterPath *path, QTextItem::RenderFlags); - - virtual const char *name() const { return "QFontEngineMac"; } - - virtual bool canRender(const QChar *string, int len); - - virtual int synthesized() const { return synthesisFlags; } - - virtual Type type() const { return QFontEngine::Mac; } - - void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight); - - virtual FaceId faceId() const; - virtual QByteArray getSfntTable(uint tag) const; - virtual Properties properties() const; - virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t); - virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); - -private: - QImage imageForGlyph(glyph_t glyph, int margin, bool colorful); - - ATSUFontID fontID; - QCFType cgFont; - ATSUStyle style; - int synthesisFlags; - mutable QGlyphLayout kashidaGlyph; - QFontEngineMacMulti *multiEngine; - mutable const unsigned char *cmap; - mutable bool symbolCMap; - mutable QByteArray cmapTable; - CGAffineTransform transform; - QFixed m_ascent; - QFixed m_descent; - QFixed m_leading; - qreal m_maxCharWidth; - QFixed m_xHeight; - QFixed m_averageCharWidth; -}; - -class QFontEngineMacMulti : public QFontEngineMulti -{ - friend class QFontEngineMac; -public: - // internal - struct ShaperItem - { - inline ShaperItem() : string(0), from(0), length(0), - log_clusters(0), charAttributes(0) {} - - const QChar *string; - int from; - int length; - QGlyphLayout glyphs; - unsigned short *log_clusters; - const HB_CharAttributes *charAttributes; - QTextEngine::ShaperFlags flags; - }; - - QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning); - virtual ~QFontEngineMacMulti(); - - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; - bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; - - virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; - virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const; - - virtual const char *name() const { return "ATSUI"; } - - virtual bool canRender(const QChar *string, int len); - - inline ATSUFontID macFontID() const { return fontID; } - -protected: - virtual void loadEngine(int at); - -private: - inline const QFontEngineMac *engineAt(int i) const - { return static_cast(engines.at(i)); } - - bool stringToCMapInternal(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, ShaperItem *item) const; - - int fontIndexForFontID(ATSUFontID id) const; - - ATSUFontID fontID; - uint kerning : 1; - - mutable ATSUTextLayout textLayout; - mutable ATSUStyle style; - CGAffineTransform transform; -}; -#endif //!QT_MAC_USE_COCOA -#endif - class QTestFontEngine : public QFontEngineBox { public: diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index 342fb5e..7002851 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -41,6 +41,9 @@ #include "qtextengine_p.h" +#include +#include + QT_BEGIN_NAMESPACE // set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 0040b54..daafdd9 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -93,9 +93,15 @@ unix:x11 { } !embedded:!qpa:!x11:mac { + HEADERS += \ + text/qfontengine_mac_p.h + OBJECTIVE_HEADERS += \ + text/qfontengine_coretext_p.h SOURCES += \ - text/qfont_mac.cpp - OBJECTIVE_SOURCES += text/qfontengine_mac.mm + text/qfont_mac.cpp + OBJECTIVE_SOURCES += \ + text/qfontengine_coretext.mm \ + text/qfontengine_mac.mm } embedded { diff --git a/src/gui/util/qdesktopservices_mac.cpp b/src/gui/util/qdesktopservices_mac.cpp index 6c5ff18..05a1789 100644 --- a/src/gui/util/qdesktopservices_mac.cpp +++ b/src/gui/util/qdesktopservices_mac.cpp @@ -49,6 +49,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE /* -- cgit v0.12 From 415358416981249dc00446ba3368be1b7c0cba51 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 29 Oct 2010 16:24:29 +0200 Subject: Compile fix for c1148ee9a60a6fae8. --- src/gui/kernel/qeventdispatcher_qpa.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp index 31fb356..519d2a6 100644 --- a/src/gui/kernel/qeventdispatcher_qpa.cpp +++ b/src/gui/kernel/qeventdispatcher_qpa.cpp @@ -332,6 +332,4 @@ void SelectWorker::run() m_edPrivate->barrierReturnValue->checkpoint(); } } - -#include "qeventdispatcher_qpa.moc" QT_END_NAMESPACE -- cgit v0.12 From 05b65c2f9df1c2c56c72f313401a6adb422d381b Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 1 Nov 2010 13:44:36 +0100 Subject: Fix cross-compilation for Lighthouse after 3d86d2a8e5e3c68f9e0022e67629 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Morten Johan Sørvig --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 08d2f54..61f2413 100755 --- a/configure +++ b/configure @@ -2938,7 +2938,7 @@ if [ '!' -f "${XQMAKESPEC}/qplatformdefs.h" ]; then fi # now look at the configs and figure out what platform we are config'd for -[ "$CFG_EMBEDDED" = "no" ] \ +[ "$CFG_EMBEDDED" = "no" ] && [ "$PLATFORM_QPA" != "yes" ] \ && [ '!' -z "`getQMakeConf \"$XQMAKESPEC\" | grep QMAKE_LIBS_X11 | awk '{print $3;}'`" ] \ && PLATFORM_X11=yes ### echo "$XQMAKESPEC" | grep mkspecs/qws >/dev/null 2>&1 && PLATFORM_QWS=yes -- cgit v0.12 From 587728bf81e60de63a80b10ae2d57b7bc18bec4e Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 16 Nov 2010 21:21:12 +0100 Subject: Add workaround_brokenFBOReadback=true for mali --- src/opengl/qgl_qpa.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 49c0860..4b530de 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -166,6 +166,15 @@ void QGLContext::makeCurrent() Q_D(QGLContext); d->platformContext->makeCurrent(); QGLContextPrivate::setCurrentContext(this); + + if (!d->workaroundsCached) { + d->workaroundsCached = true; + const char *renderer = reinterpret_cast(glGetString(GL_RENDERER)); + if (renderer && strstr(renderer, "Mali")) { + d->workaround_brokenFBOReadBack = true; + } + } + } void QGLContext::doneCurrent() -- cgit v0.12 From 687d44569dbccea72c582c6d7da9a271ae2c86c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Mon, 15 Nov 2010 16:18:25 +0100 Subject: No more windowsurface for QGLWidget in Lighthouse Reviewed-by: paul --- src/gui/kernel/qplatformwindowformat_qpa.cpp | 39 ++++++++++++++-------------- src/gui/kernel/qplatformwindowformat_qpa.h | 16 +++++++----- src/gui/kernel/qwidget_qpa.cpp | 7 +++-- src/opengl/qgl_qpa.cpp | 1 + 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp index d497e85..f0dad17 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.cpp +++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp @@ -53,7 +53,7 @@ public: , opts(QPlatformWindowFormat::DoubleBuffer | QPlatformWindowFormat::DepthBuffer | QPlatformWindowFormat::Rgba | QPlatformWindowFormat::DirectRendering | QPlatformWindowFormat::StencilBuffer | QPlatformWindowFormat::DeprecatedFunctions - | QPlatformWindowFormat::UseDefaultSharedContext) + | QPlatformWindowFormat::UseDefaultSharedContext | QPlatformWindowFormat::HasWindowSurface) , depthSize(-1) , accumSize(-1) , stencilSize(-1) @@ -616,31 +616,32 @@ QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const return d->sharedContext; } -///*! -// \fn bool QPlatformWindowFormat::hasOverlay() const +/*! + \fn bool QPlatformWindowFormat::hasWindowSurface() const -// Returns true if overlay plane is enabled; otherwise returns false. + Returns true if the corresponding widget has an instance of QWindowSurface. -// Overlay is disabled by default. + Otherwise returns false. -// \sa setOverlay() -//*/ + WindowSurface is enabled by default. -///*! -// If \a enable is true enables an overlay plane; otherwise disables -// the overlay plane. + \sa setOverlay() +*/ -// Enabling the overlay plane will cause QGLWidget to create an -// additional context in an overlay plane. See the QGLWidget -// documentation for further information. +/*! + If \a enable is true a top level QWidget will create a QWindowSurface at creation; -// \sa hasOverlay() -//*/ + otherwise the QWidget will only have a QPlatformWindow. -//void QPlatformWindowFormat::setOverlay(bool enable) -//{ -// setOption(enable ? QPlatformWindowFormat::HasOverlay : QPlatformWindowFormat::NoOverlay); -//} + This is usefull for ie. QGLWidget where the QPlatformGLContext controlls the surface. + + \sa hasOverlay() +*/ + +void QPlatformWindowFormat::setWindowSurface(bool enable) +{ + setOption(enable ? QPlatformWindowFormat::HasWindowSurface : QPlatformWindowFormat::NoWindowSurface); +} /*! Sets the format option to \a opt. diff --git a/src/gui/kernel/qplatformwindowformat_qpa.h b/src/gui/kernel/qplatformwindowformat_qpa.h index 63df76a..790385b 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.h +++ b/src/gui/kernel/qplatformwindowformat_qpa.h @@ -67,6 +67,7 @@ public: SampleBuffers = 0x0200, DeprecatedFunctions = 0x0400, UseDefaultSharedContext = 0x0800, + HasWindowSurface = 0x1000, SingleBuffer = DoubleBuffer << 16, NoDepthBuffer = DepthBuffer << 16, ColorIndex = Rgba << 16, @@ -78,7 +79,8 @@ public: NoOverlay = HasOverlay << 16, NoSampleBuffers = SampleBuffers << 16, NoDeprecatedFunctions = DeprecatedFunctions << 16, - NoDefaultSharedContext = UseDefaultSharedContext << 16 + NoDefaultSharedContext = UseDefaultSharedContext << 16, + NoWindowSurface = HasWindowSurface << 16 }; Q_DECLARE_FLAGS(FormatOptions, FormatOption) @@ -149,8 +151,8 @@ public: void setDirectRendering(bool enable); bool useDefaultSharedContext() const; void setUseDefaultSharedContext(bool enable); -// bool hasOverlay() const; -// void setOverlay(bool enable); + bool hasWindowSurface() const; + void setWindowSurface(bool enable); void setOption(QPlatformWindowFormat::FormatOptions opt); bool testOption(QPlatformWindowFormat::FormatOptions opt) const; @@ -219,10 +221,10 @@ inline bool QPlatformWindowFormat::directRendering() const return testOption(QPlatformWindowFormat::DirectRendering); } -//inline bool QPlatformWindowFormat::hasOverlay() const -//{ -// return testOption(QPlatformWindowFormat::HasOverlay); -//} +inline bool QPlatformWindowFormat::hasWindowSurface() const +{ + return testOption(QPlatformWindowFormat::HasWindowSurface); +} inline bool QPlatformWindowFormat::sampleBuffers() const { diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index ac8b37d..aff959e 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -97,7 +97,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } Q_ASSERT(platformWindow); - if (!surface) { + if (!surface && platformWindow && q->platformWindowFormat().hasWindowSurface()) { surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId()); } @@ -831,7 +831,10 @@ QPaintEngine *QWidget::paintEngine() const QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys() { Q_Q(QWidget); - return QApplicationPrivate::platformIntegration()->createWindowSurface(q,0); + if (q->platformWindowFormat().hasWindowSurface()) + return QApplicationPrivate::platformIntegration()->createWindowSurface(q,0); + else + return 0; } void QWidgetPrivate::setModal_sys() diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 4b530de..1197013 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -134,6 +134,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) winFormat.setSharedContext(shareContext->d_func()->platformContext); } winFormat.setWindowApi(QPlatformWindowFormat::OpenGL); + winFormat.setWindowSurface(false); widget->setPlatformWindowFormat(winFormat); widget->winId();//make window } -- cgit v0.12 From 9d00cf202376c2b02dec27b362cf88a00e952e88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 16 Nov 2010 08:51:17 +0100 Subject: Lighthouse: using QFont enums when possible in QPlatformFontdatabase also, make it possible to register fonts in QPlatformDatabases with a null handle Reviewed-by: paul --- src/gui/text/qfontdatabase_qpa.cpp | 11 ++++------- src/gui/text/qplatformfontdatabase_qpa.cpp | 12 ++++++------ src/gui/text/qplatformfontdatabase_qpa.h | 4 ++-- .../fontdatabases/basicunix/qbasicunixfontdatabase.cpp | 6 ++++-- .../fontdatabases/fontconfig/qfontconfigdatabase.cpp | 14 +++++++++----- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index 19ce1be..e54093c 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -156,14 +156,11 @@ QFontEngine *loadSingleEngine(int script, QFontEngine *engine = QFontCache::instance()->findEngine(key); if (!engine) { QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase(); - if (size->handle) { - engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle); - if (engine) { - QFontCache::Key key(def,script); - QFontCache::instance()->instance()->insertEngine(key,engine); - } + engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle); + if (engine) { + QFontCache::Key key(def,script); + QFontCache::instance()->instance()->insertEngine(key,engine); } - } return engine; } diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 370c921..7a89fe4 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -65,9 +65,9 @@ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void * QByteArray writingSystemBits = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_WritingSystems).toByteArray(); if (!fontName.isEmpty() && pixelSize) { - int fontWeight = 50; + QFont::Weight fontWeight = QFont::Normal; if (weight.type() == QVariant::Int || weight.type() == QVariant::UInt) - fontWeight = weight.toInt(); + fontWeight = QFont::Weight(weight.toInt()); QFont::Style fontStyle = static_cast(style.toInt()); @@ -80,16 +80,16 @@ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void * currentByte >>= 1; } } - - registerFont(fontName,QString(),fontWeight,fontStyle,100,true,false,pixelSize,writingSystems,handle); + QFont::Stretch stretch = QFont::Unstretched; + registerFont(fontName,QString(),fontWeight,fontStyle,stretch,true,false,pixelSize,writingSystems,handle); } } else { qDebug() << "header verification of QPF2 font failed. maybe it is corrupt?"; } } -void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, int weight, - QFont::Style style, int stretch, bool antialiased, bool scalable, int pixelSize, +void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight, + QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *usrPtr) { if (scalable) diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h index 75b0a18..aa465ab 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.h +++ b/src/gui/text/qplatformfontdatabase_qpa.h @@ -96,8 +96,8 @@ public: //callback static void registerQPF2Font(const QByteArray &dataArray, void *handle); - static void registerFont(const QString &familyname, const QString &foundryname, int weight, - QFont::Style style, int stetch, bool antialiased, bool scalable, int pixelSize, + static void registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight, + QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *handle); }; diff --git a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp index 4634477..ee520be 100644 --- a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp +++ b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp @@ -278,7 +278,7 @@ QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const } numFaces = face->num_faces; - int weight = QFont::Normal; + QFont::Weight weight = QFont::Normal; QFont::Style style = QFont::StyleNormal; if (face->style_flags & FT_STYLE_FLAG_ITALIC) @@ -315,7 +315,9 @@ QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const fontFile->fileName = file; fontFile->indexValue = index; - registerFont(family,"",weight,style,100,true,true,0,writingSystems,fontFile); + QFont::Stretch stretch = QFont::Unstretched; + + registerFont(family,"",weight,style,stretch,true,true,0,writingSystems,fontFile); families.append(family); diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp index c9d1b74..92f30fc 100644 --- a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -395,7 +395,7 @@ void QFontconfigDatabase::populateFontDatabase() : ((slant_value == FC_SLANT_OBLIQUE) ? QFont::StyleOblique : QFont::StyleNormal); - int weight = getFCWeight(weight_value); + QFont::Weight weight = QFont::Weight(getFCWeight(weight_value)); double pixel_size = 0; if (!scalable) { @@ -404,7 +404,8 @@ void QFontconfigDatabase::populateFontDatabase() FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size); } - QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,100,antialias,scalable,pixel_size,writingSystems,fontFile); + QFont::Stretch stretch = QFont::Unstretched; + QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,writingSystems,fontFile); // qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size; } @@ -426,10 +427,11 @@ void QFontconfigDatabase::populateFontDatabase() QSupportedWritingSystems ws; ws.setSupported(QFontDatabase::Latin); + while (f->qtname) { - registerFont(f->qtname,"",50,QFont::StyleNormal,100,true,true,0,ws,0); - registerFont(f->qtname,"",50,QFont::StyleItalic,100,true,true,0,ws,0); - registerFont(f->qtname,"",50,QFont::StyleOblique,100,true,true,0,ws,0); + registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,ws,0); + registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,ws,0); + registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,ws,0); ++f; } @@ -444,6 +446,8 @@ void QFontconfigDatabase::populateFontDatabase() QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr) { + if (!usrPtr) + return 0; QFontDef fontDef = f; QFontEngineFT *engine; -- cgit v0.12 From 799e7456268e347356cf4949fcab525968e9fea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 16 Nov 2010 10:51:28 +0100 Subject: Lighthouse: Make sure that we call QPlatformWindow::setVisible on native child widgets. Reviewed-by: paul --- src/gui/kernel/qwidget_qpa.cpp | 35 ++++++++++------------ src/plugins/platforms/testlite/qtestlitewindow.cpp | 1 - 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index aff959e..acb2615 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -392,25 +392,22 @@ void QWidgetPrivate::show_sys() QPlatformWindow *window = q->platformWindow(); if (window) { - const QRect geomRect = q->geometry(); - const QRect windowRect = window->geometry(); - if (windowRect != geomRect) { - window->setGeometry(geomRect); - } - if (q->isWindow()) { - if (QWindowSurface *surface = q->windowSurface()) { - if (windowRect.size() != geomRect.size()) { - surface->resize(geomRect.size()); - } - } - - if (window) - window->setVisible(true); - - if (q->windowType() != Qt::Popup && q->windowType() != Qt::ToolTip && !(q->windowFlags() & Qt::X11BypassWindowManagerHint)) - q->activateWindow(); //### - } - } + const QRect geomRect = q->geometry(); + const QRect windowRect = window->geometry(); + if (windowRect != geomRect) { + window->setGeometry(geomRect); + } + if (QWindowSurface *surface = q->windowSurface()) { + if (windowRect.size() != geomRect.size()) { + surface->resize(geomRect.size()); + } + } + if (window) + window->setVisible(true); + + if (q->isWindow() && q->windowType() != Qt::Popup && q->windowType() != Qt::ToolTip && !(q->windowFlags() & Qt::X11BypassWindowManagerHint)) + q->activateWindow(); //### QWindowSystemInterface should have callback function for when WS actually activates window. + } } diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp index 1de4b9d..9f3c435 100644 --- a/src/plugins/platforms/testlite/qtestlitewindow.cpp +++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp @@ -649,7 +649,6 @@ void QTestLiteWindow::setParent(const QPlatformWindow *window) { QPoint point = widget()->mapTo(widget()->nativeParentWidget(),QPoint()); XReparentWindow(xd->display,x_window,window->winId(),point.x(),point.y()); - XMapWindow(xd->display, x_window); } void QTestLiteWindow::raise() -- cgit v0.12 From 6901d3a9ff05a6fbf13ef7f38a36ad21d20f6a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 16 Nov 2010 12:45:15 +0100 Subject: Fix transformIsSimple in QGraphicsScene The transformIsSimple was a bit to restrictive Reviewed-by: bnilsen --- src/gui/graphicsview/qgraphicsscene.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 981fbbc..19b2cb8 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4367,25 +4367,8 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion & static inline bool transformIsSimple(const QTransform& transform) { QTransform::TransformationType type = transform.type(); - if (type == QTransform::TxNone || type == QTransform::TxTranslate) { + if (type <= QTransform::TxScale) { return true; - } else if (type == QTransform::TxScale) { - // Check for 0 and 180 degree rotations. - // (0 might happen after 4 rotations of 90 degrees). - qreal m11 = transform.m11(); - qreal m12 = transform.m12(); - qreal m21 = transform.m21(); - qreal m22 = transform.m22(); - if (m12 == 0.0f && m21 == 0.0f) { - if (m11 == 1.0f && m22 == 1.0f) - return true; // 0 degrees - else if (m11 == -1.0f && m22 == -1.0f) - return true; // 180 degrees. - if(m11 == 1.0f && m22 == -1.0f) - return true; // 0 degrees inverted y. - else if(m11 == -1.0f && m22 == 1.0f) - return true; // 180 degrees inverted y. - } } else if (type == QTransform::TxRotate) { // Check for 90, and 270 degree rotations. qreal m11 = transform.m11(); -- cgit v0.12 From a1acef227647b3043998f9ccf364ead5c29b882d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 18 Nov 2010 10:30:21 +0100 Subject: Remove QWidget::paintEngine() codepath for Lighthouse Reviewed-by: paul --- src/gui/painting/qbackingstore.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index df1210f..c051228 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -1620,7 +1620,11 @@ void QWidgetPrivate::repaint_sys(const QRegion &rgn) extra->staticContentsSize = data.crect.size(); } +#ifdef Q_WS_QPA //Dont even call q->p + QPaintEngine *engine = 0; +#else QPaintEngine *engine = q->paintEngine(); +#endif // QGLWidget does not support partial updates if: // 1) The context is double buffered // 2) The context is single buffered and auto-fill background is enabled. -- cgit v0.12 From 292f6a9ba1b5da049e4898525974c6f0575ccd65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 18 Nov 2010 13:03:59 +0100 Subject: Lighthouse: move the currentContext functionality to QPlatformGLContext This means the threading functionality has been delegated down to QPlatformGLContext. However, it is still possible to use QGLContext::currentContext to retrieve the QGLContext. This so that QGLFunctions, QGLShaderProgram etc can be used without a QGLWidget. Reviewed-by: paul --- src/gui/kernel/qplatformglcontext_qpa.cpp | 116 ++++++++++++++++++++- src/gui/kernel/qplatformglcontext_qpa.h | 23 +++- src/gui/kernel/qwidget_qpa.cpp | 12 +++ src/opengl/qgl.cpp | 24 +++++ src/opengl/qgl.h | 8 ++ src/opengl/qgl_qpa.cpp | 22 ++-- .../eglconvenience/qeglplatformcontext.cpp | 6 +- .../platforms/eglconvenience/qeglplatformcontext.h | 2 +- src/plugins/platforms/testlite/qglxintegration.cpp | 12 ++- src/plugins/platforms/testlite/qglxintegration.h | 4 +- src/plugins/platforms/testlite/qtestlitewindow.cpp | 2 +- 11 files changed, 205 insertions(+), 26 deletions(-) diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp index 36db2b0..5ed1d3d 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ b/src/gui/kernel/qplatformglcontext_qpa.cpp @@ -41,17 +41,123 @@ #include "qplatformglcontext_qpa.h" +#include +#include + +#include + +class QPlatformGLThreadContext +{ +public: + ~QPlatformGLThreadContext() { + if (context) + context->doneCurrent(); + } + QPlatformGLContext *context; +}; + +static QThreadStorage qplatformgl_context_storage; + +class QPlatformGLContextPrivate +{ +public: + QPlatformGLContextPrivate(QPlatformWindow *platformWindow) + :qGLContextHandle(0),platformWindow(platformWindow) + { + } + + virtual ~QPlatformGLContextPrivate() + { + //do not delete the QGLContext handle here as it is deleted in + //QWidgetPrivate::deleteTLSysExtra() + } + void *qGLContextHandle; + void (*qGLContextDeleteFunction)(void *handle); + QPlatformWindow *platformWindow; + static QPlatformGLContext *staticSharedContext; + + static void setCurrentContext(QPlatformGLContext *context); +}; + +QPlatformGLContext *QPlatformGLContextPrivate::staticSharedContext = 0; + +void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context) +{ + QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData(); + if (!threadContext) { + if (!QThread::currentThread()) { + qWarning("No QTLS available. currentContext wont work"); + return; + } + threadContext = new QPlatformGLThreadContext; + qplatformgl_context_storage.setLocalData(threadContext); + } + threadContext->context = context; +} + +QPlatformWindow *QPlatformGLContext::platformWindow() const +{ + Q_D(const QPlatformGLContext); + return d->platformWindow; +} + +const QPlatformGLContext* QPlatformGLContext::currentContext() +{ + QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData(); + if(threadContext) { + return threadContext->context; + } + return 0; +} + +QPlatformGLContext::QPlatformGLContext(QPlatformWindow *platformWindow) + :d_ptr(new QPlatformGLContextPrivate(platformWindow)) +{ +} + QPlatformGLContext::~QPlatformGLContext() -{ } +{ + if (QPlatformGLContext::currentContext() == this) { + doneCurrent(); + } -static QPlatformGLContext *staticSharedContext = 0; +} void QPlatformGLContext::setDefaultSharedContext(QPlatformGLContext *sharedContext) { - staticSharedContext = sharedContext; + QPlatformGLContextPrivate::staticSharedContext = sharedContext; +} + +const QPlatformGLContext *QPlatformGLContext::defaultSharedContext() +{ + return QPlatformGLContextPrivate::staticSharedContext; +} + +void QPlatformGLContext::makeCurrent() +{ + QPlatformGLContextPrivate::setCurrentContext(this); +} + +void QPlatformGLContext::doneCurrent() +{ + QPlatformGLContextPrivate::setCurrentContext(0); +} + +void *QPlatformGLContext::qGLContextHandle() const +{ + Q_D(const QPlatformGLContext); + return d->qGLContextHandle; +} + +void QPlatformGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)) +{ + Q_D(QPlatformGLContext); + d->qGLContextHandle = handle; + d->qGLContextDeleteFunction = qGLContextDeleteFunction; } -QPlatformGLContext *QPlatformGLContext::defaultSharedContext() +void QPlatformGLContext::deleteQGLContext() { - return staticSharedContext; + Q_D(QPlatformGLContext); + d->qGLContextDeleteFunction(d->qGLContextHandle); } diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h index ed41723..3e10c2b 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.h +++ b/src/gui/kernel/qplatformglcontext_qpa.h @@ -51,24 +51,41 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) +class QPlatformGLContextPrivate; + class Q_OPENGL_EXPORT QPlatformGLContext { +Q_DECLARE_PRIVATE(QPlatformGLContext); + public: + explicit QPlatformGLContext(QPlatformWindow *platformWindow); virtual ~QPlatformGLContext(); - virtual void makeCurrent() = 0; - virtual void doneCurrent() = 0; + virtual void makeCurrent(); + virtual void doneCurrent(); virtual void swapBuffers() = 0; virtual void* getProcAddress(const QString& procName) = 0; virtual QPlatformWindowFormat platformWindowFormat() const = 0; - static QPlatformGLContext *defaultSharedContext(); + QPlatformWindow *platformWindow() const; + + const static QPlatformGLContext *currentContext(); + const static QPlatformGLContext *defaultSharedContext(); protected: static void setDefaultSharedContext(QPlatformGLContext *sharedContext); + QScopedPointer d_ptr; +private: + //hack to make it work with QGLContext::CurrentContext + friend class QGLContext; + friend class QWidgetPrivate; + void *qGLContextHandle() const; + void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)); + void deleteQGLContext(); + Q_DISABLE_COPY(QPlatformGLContext); }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index acb2615..aa6b3f8 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -48,6 +48,7 @@ #include "QtGui/private/qapplication_p.h" #include "QtGui/qdesktopwidget.h" #include "QtGui/qplatformwindow_qpa.h" +#include "QtGui/qplatformglcontext_qpa.h" #include @@ -99,6 +100,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (!surface && platformWindow && q->platformWindowFormat().hasWindowSurface()) { surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId()); + } else { + q->setAttribute(Qt::WA_PaintOnScreen,true); } data.window_flags = q->platformWindow()->setWindowFlags(data.window_flags); @@ -784,6 +787,15 @@ void QWidgetPrivate::createTLSysExtra() void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) { + if (extra->topextra->platformWindowFormat.windowApi() == QPlatformWindowFormat::OpenGL) { + //the toplevel might have a context with a "qglcontext assosiated with it. We need to + //delete the qglcontext before we delete the qplatformglcontext. + if (extra->topextra->platformWindow) { + if (QPlatformGLContext *context = extra->topextra->platformWindow->glContext()) { + context->deleteQGLContext(); + } + } + } delete extra->topextra->platformWindow; extra->topextra->platformWindow = 0; extra->topextra->backingStore.destroy(); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index cf45239..65d3bbe 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -79,6 +79,10 @@ #include #endif +#ifdef Q_WS_QPA +#include +#endif + #include #include @@ -117,7 +121,9 @@ struct QGLThreadContext { QGLContext *context; }; +#ifndef Q_WS_QPA static QThreadStorage qgl_context_storage; +#endif Q_GLOBAL_STATIC(QGLFormat, qgl_default_format) @@ -3381,14 +3387,31 @@ void QGLContext::setInitialized(bool on) const QGLContext* QGLContext::currentContext() { +#ifdef Q_WS_QPA + if (const QPlatformGLContext *threadContext = QPlatformGLContext::currentContext()) { + if (threadContext->qGLContextHandle()) { + return (const QGLContext *)threadContext->qGLContextHandle(); + } else { + QWidget *widget = threadContext->platformWindow()->widget(); + QGLContext *context = new QGLContext(QGLFormat::fromPlatformWindowFormat(threadContext->platformWindowFormat()),widget); + context->create(); //don't know how to pass in the sharecontext. (doesn't really matter though) + return context; + } + } + return 0; +#else QGLThreadContext *threadContext = qgl_context_storage.localData(); if (threadContext) return threadContext->context; return 0; +#endif //Q_WS_QPA } void QGLContextPrivate::setCurrentContext(QGLContext *context) { +#ifdef Q_WS_QPA + Q_UNUSED(context); +#else QGLThreadContext *threadContext = qgl_context_storage.localData(); if (!threadContext) { if (!QThread::currentThread()) { @@ -3401,6 +3424,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context) } threadContext->context = context; QGLContext::currentCtx = context; // XXX: backwards-compat, not thread-safe +#endif } /*! diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 4f10e5c..1f864a3 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -48,6 +48,10 @@ #include #include +#ifdef Q_WS_QPA +#include +#endif + QT_BEGIN_HEADER #if defined(Q_WS_WIN) @@ -270,6 +274,10 @@ public: static OpenGLVersionFlags openGLVersionFlags(); +#if defined(Q_WS_QPA) + static QGLFormat fromPlatformWindowFormat(const QPlatformWindowFormat &format); + static QPlatformWindowFormat toPlatformWindowFormat(const QGLFormat &format); +#endif private: QGLFormatPrivate *d; diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 1197013..28bea83 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE -static QGLFormat qt_platformwindowformat_to_glformat(const QPlatformWindowFormat &format) +QGLFormat QGLFormat::fromPlatformWindowFormat(const QPlatformWindowFormat &format) { QGLFormat retFormat; retFormat.setAccum(format.accum()); @@ -83,7 +83,7 @@ static QGLFormat qt_platformwindowformat_to_glformat(const QPlatformWindowFormat return retFormat; } -static QPlatformWindowFormat qt_glformat_to_platformwindowformat(const QGLFormat &format) +QPlatformWindowFormat QGLFormat::toPlatformWindowFormat(const QGLFormat &format) { QPlatformWindowFormat retFormat; retFormat.setAccum(format.accum()); @@ -120,6 +120,12 @@ bool QGLFormat::hasOpenGL() return QApplicationPrivate::platformIntegration()->hasOpenGL(); } +void qDeleteQGLContext(void *handle) +{ + QGLContext *context = static_cast(handle); + delete context; +} + bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); @@ -129,7 +135,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) QWidget *widget = static_cast(d->paintDevice); if (!widget->platformWindow()){ QGLFormat glformat = format(); - QPlatformWindowFormat winFormat = qt_glformat_to_platformwindowformat(glformat); + QPlatformWindowFormat winFormat = QGLFormat::toPlatformWindowFormat(glformat); if (shareContext) { winFormat.setSharedContext(shareContext->d_func()->platformContext); } @@ -140,8 +146,11 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) } d->platformContext = widget->platformWindow()->glContext(); Q_ASSERT(d->platformContext); - d->glFormat = qt_platformwindowformat_to_glformat(d->platformContext->platformWindowFormat()); + d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat()); d->valid =(bool) d->platformContext; + if (d->valid) { + d->platformContext->setQGLContextHandle(this,qDeleteQGLContext); + } } return d->valid; @@ -254,13 +263,13 @@ class QGLTemporaryContextPrivate { public: QWidget *widget; - QGLContext *context; + QPlatformGLContext *context; }; QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) : d(new QGLTemporaryContextPrivate) { - d->context = const_cast(QGLContext::currentContext()); + d->context = const_cast(QPlatformGLContext::currentContext()); if (d->context) d->context->doneCurrent(); d->widget = new QWidget; @@ -269,7 +278,6 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) format.setWindowApi(QPlatformWindowFormat::OpenGL); d->widget->winId(); - d->widget->platformWindow()->glContext()->makeCurrent(); } diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp index ae3b539..a169c35 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp @@ -48,8 +48,8 @@ #include -QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi) - : QPlatformGLContext() +QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow) + : QPlatformGLContext(platformWindow) , m_eglDisplay(display) , m_eglSurface(surface) , m_eglApi(eglApi) @@ -88,6 +88,7 @@ QEGLPlatformContext::~QEGLPlatformContext() void QEGLPlatformContext::makeCurrent() { + QPlatformGLContext::makeCurrent(); #ifdef QEGL_EXTRA_DEBUG qWarning("QEglContext::makeCurrent: %p\n",this); #endif @@ -117,6 +118,7 @@ void QEGLPlatformContext::makeCurrent() } void QEGLPlatformContext::doneCurrent() { + QPlatformGLContext::doneCurrent(); #ifdef QEGL_EXTRA_DEBUG qWarning("QEglContext::doneCurrent:%p\n",this); #endif diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h index ae1a891..2c38aca 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h @@ -48,7 +48,7 @@ class QEGLPlatformContext : public QPlatformGLContext { public: - QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi); + QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow); ~QEGLPlatformContext(); void makeCurrent(); diff --git a/src/plugins/platforms/testlite/qglxintegration.cpp b/src/plugins/platforms/testlite/qglxintegration.cpp index e262d5b..c35db9b 100644 --- a/src/plugins/platforms/testlite/qglxintegration.cpp +++ b/src/plugins/platforms/testlite/qglxintegration.cpp @@ -235,14 +235,14 @@ QPlatformWindowFormat QGLXGLContext::reducePlatformWindowFormat(const QPlatformW return retFormat; } -QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format) - : QPlatformGLContext() +QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format) + : QPlatformGLContext(platformWindow) , m_xd(xd) , m_drawable((Drawable)window) , m_context(0) { - QPlatformGLContext *sharePlatformContext; + const QPlatformGLContext *sharePlatformContext; if (format.useDefaultSharedContext()) { if (!QPlatformGLContext::defaultSharedContext()) { if (m_defaultSharedContextMutex.tryLock()){ @@ -259,7 +259,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindow } GLXContext shareGlxContext = 0; if (sharePlatformContext) - shareGlxContext = static_cast(sharePlatformContext)->glxContext(); + shareGlxContext = static_cast(sharePlatformContext)->glxContext(); GLXFBConfig config = findConfig(xd,format); m_context = glXCreateNewContext(xd->display,config,GLX_RGBA_TYPE,shareGlxContext,TRUE); @@ -271,7 +271,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindow } QGLXGLContext::QGLXGLContext(MyDisplay *display, Drawable drawable, GLXContext context) - : QPlatformGLContext(), m_xd(display), m_drawable(drawable), m_context(context) + : QPlatformGLContext(0), m_xd(display), m_drawable(drawable), m_context(context) { } @@ -313,6 +313,7 @@ void QGLXGLContext::createDefaultSharedContex(MyDisplay *xd) void QGLXGLContext::makeCurrent() { + QPlatformGLContext::makeCurrent(); #ifdef MYX11_DEBUG qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", m_drawable, m_context); #endif @@ -321,6 +322,7 @@ void QGLXGLContext::makeCurrent() void QGLXGLContext::doneCurrent() { + QPlatformGLContext::doneCurrent(); glXMakeCurrent(m_xd->display, 0, 0); } diff --git a/src/plugins/platforms/testlite/qglxintegration.h b/src/plugins/platforms/testlite/qglxintegration.h index 479be4b..432dec5 100644 --- a/src/plugins/platforms/testlite/qglxintegration.h +++ b/src/plugins/platforms/testlite/qglxintegration.h @@ -58,7 +58,7 @@ class MyDisplay; class QGLXGLContext : public QPlatformGLContext { public: - QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format); + QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format); ~QGLXGLContext(); virtual void makeCurrent(); @@ -66,7 +66,7 @@ public: virtual void swapBuffers(); virtual void* getProcAddress(const QString& procName); - GLXContext glxContext() {return m_context;} + GLXContext glxContext() const {return m_context;} QPlatformWindowFormat platformWindowFormat() const; diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp index 9f3c435..0a6e1ff 100644 --- a/src/plugins/platforms/testlite/qtestlitewindow.cpp +++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp @@ -1021,7 +1021,7 @@ QPlatformGLContext *QTestLiteWindow::glContext() const if (!mGLContext) { QTestLiteWindow *that = const_cast(this); #ifndef QT_NO_OPENGL - that->mGLContext = new QGLXGLContext(x_window, xd, widget()->platformWindowFormat()); + that->mGLContext = new QGLXGLContext(x_window, xd, that,widget()->platformWindowFormat()); #endif } return mGLContext; -- cgit v0.12 From b24c0c77610c29442d538d4d33d6e0c53e88ae00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 19 Nov 2010 11:58:59 +0100 Subject: Adding some documentation for Lighthouse The spirit here is "something is better than nothing". Ie. its the first itteration of documenting the classes. No general Lighthouse introduction yet... --- src/gui/kernel/qplatformglcontext_qpa.cpp | 70 ++++++++++++++++ src/gui/kernel/qplatformintegration_qpa.cpp | 119 +++++++++++++++++++++++++++ src/gui/kernel/qplatformintegration_qpa.h | 2 +- src/gui/kernel/qplatformscreen_qpa.cpp | 48 +++++++++++ src/gui/kernel/qplatformscreen_qpa.h | 1 + src/gui/kernel/qplatformwindow_qpa.cpp | 89 +++++++++++++++++++- src/gui/kernel/qplatformwindow_qpa.h | 2 +- src/gui/kernel/qplatformwindowformat_qpa.cpp | 12 ++- src/gui/painting/qwindowsurface.cpp | 11 ++- src/gui/text/qplatformfontdatabase_qpa.cpp | 49 +++++++++++ 10 files changed, 393 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp index 5ed1d3d..a450b33 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ b/src/gui/kernel/qplatformglcontext_qpa.cpp @@ -95,12 +95,18 @@ void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context) threadContext->context = context; } +/*! + Returns the platformWindow which this QPlatformGLContext belongs to. +*/ QPlatformWindow *QPlatformGLContext::platformWindow() const { Q_D(const QPlatformGLContext); return d->platformWindow; } +/*! + Returns the last context which called makeCurrent. This function is thread aware. +*/ const QPlatformGLContext* QPlatformGLContext::currentContext() { QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData(); @@ -110,11 +116,17 @@ const QPlatformGLContext* QPlatformGLContext::currentContext() return 0; } +/*! + All subclasses needs to specify the platformWindow. It can be a null window. +*/ QPlatformGLContext::QPlatformGLContext(QPlatformWindow *platformWindow) :d_ptr(new QPlatformGLContextPrivate(platformWindow)) { } +/*! + If this is the current context for the thread, doneCurrent is called +*/ QPlatformGLContext::~QPlatformGLContext() { if (QPlatformGLContext::currentContext() == this) { @@ -123,26 +135,45 @@ QPlatformGLContext::~QPlatformGLContext() } + +/*! + Makes it possible to set the context which can be the default for making new contexts. +*/ void QPlatformGLContext::setDefaultSharedContext(QPlatformGLContext *sharedContext) { QPlatformGLContextPrivate::staticSharedContext = sharedContext; } +/*! + Default shared context is intended to be a globally awailable pointer to a context which can + be used for sharing resources when creating new contexts. Its default value is 0; +*/ const QPlatformGLContext *QPlatformGLContext::defaultSharedContext() { return QPlatformGLContextPrivate::staticSharedContext; } +/*! + Reimplement in subclass to do makeCurrent on native GL context +*/ void QPlatformGLContext::makeCurrent() { QPlatformGLContextPrivate::setCurrentContext(this); } +/*! + Reimplement in subclass to release current context. + Typically this is calling makeCurrent with 0 "surface" +*/ void QPlatformGLContext::doneCurrent() { QPlatformGLContextPrivate::setCurrentContext(0); } +/* + internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant + have any type information. +*/ void *QPlatformGLContext::qGLContextHandle() const { Q_D(const QPlatformGLContext); @@ -161,3 +192,42 @@ void QPlatformGLContext::deleteQGLContext() Q_D(QPlatformGLContext); d->qGLContextDeleteFunction(d->qGLContextHandle); } + +/*! + \class QPlatformGLContext + \since 4.8 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformGLContext class provides an abstraction for native GL contexts. + + In QPA the way to support OpenGL or OpenVG or other technologies that requires a native GL + context is through the QPlatformGLContext wrapper. + + There is no factory function for QPlatformGLContexts, but rather only one accessor function. + The only place to retrieve a QPlatformGLContext from is through a QPlatformWindow. + + The context which is current for a specific thread can be collected by the currentContext() + function. This is how QPlatformGLContext also makes it possible to use the QtOpenGL module + withhout using QGLWidget. When using QGLContext::currentContext(), it will ask + QPlatformGLContext for the currentContext. Then a corresponding QGLContext will be returned, + which maps to the QPlatformGLContext. +*/ + +/*! \fn void swapBuffers() + Reimplement in subclass to native swap buffers calls +*/ + +/*! getProcAddress(const QString& procName) + Reimplement in subclass to native getProcAddr calls. + + Note: its convenient to use qPrintable(const QString &str) to get the const char * pointer +*/ + +/*! platformWindowFormat() const + QWidget has the function qplatformWindowFormat(). That function is for the application + programmer to request the format of the window and the context that he wants. + + Reimplement this function in a subclass to indicate what format the glContext actually has. +*/ diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index e2a493d..2a9bf77 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -55,16 +55,35 @@ QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, in return QPixmap(); } +/*! + Factory function for the eventloop integration interface. + + Default implementation returns 0, which causes the eventloop to run in a single thread mode. + + \sa QPlatformEventLoopIntegration +*/ QPlatformEventLoopIntegration *QPlatformIntegration::createEventLoopIntegration() const { return 0; } +/*! + Returns wheter the given platform integration supports OpenGL. + + Default implementation returns false, +*/ bool QPlatformIntegration::hasOpenGL() const { return false; } +/*! + Accessor for the platform integrations fontdatabase. + + Default implementation returns a default QPlatformFontDatabase. + + \sa QPlatformFontDatabase +*/ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const { static QPlatformFontDatabase *db = 0; @@ -74,4 +93,104 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const return db; } +/*! + \class QPlatformIntegration + \since 4.8 + \internal + \preliminary + \ingroup qpa + \brief The QPlatformIntegration class is the entry for WindowSystem specific functionality. + + QPlatformIntegration is the single entry point for windowsystem specific functionality when + using the QPA platform. It has factory functions for creating platform specific pixmaps and + windows. The class also controlls the font subsystem. + + QPlatformIntegration is a singelton class which gets instansiated in the QApplication + constructor. The QPlatformIntegration instance do not have ownership of objects it creates in + functions where the name starts with create. However, functions which don't have a name + starting with create acts as assessors to member variables. + + It is not trivial to create or build a platform plugin outside of the Qt source tree. Therefor + the recommended approach for making new platform plugin is to copy an existing plugin inside + the QTSRCTREE/src/plugins/platform and develop the plugin inside the source tree. + + The minimal platformintegration is the smallest platform integration it is possible to make, + which makes it an ideal starting point for new plugins. For a slightly more advanced plugin, + consider reviewing the directfb plugin, or the testlite plugin. +*/ + +/*! + \fn QPixmapData *createPixmapData(QPixmapData::PixelType type) const + + Factory function for QPixmapData. PixelType can be either PixmapType or BitmapType. + \sa QPixmapData +*/ + +/*! + \fn QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const + + Factory function for QPlatformWindow. The widget parameter is a pointer to the top level + widget(tlw) which the QPlatformWindow is suppose to be created for. The WId handle is actually + never used, but there for future reference. Its purpose is if it is going to be possible to + create QPlatformWindows on existing WId. + + All tlw has to have a QPlatformWindow, and it will be created when the QPlatformWindow is set + to be visible for the first time. If the tlw's window flags are changed, or if the tlw's + QPlatformWindowFormat is changed, then the tlw's QPlatformWindow is deleted and a new one is + created. + + \sa QPlatformWindow, QPlatformWindowFormat + \sa createWindowSurface(QWidget *widget, WId winId) const +*/ + +/*! + \fn QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const + + Factory function for QWindowSurface. The QWidget parameter is a pointer to the + top level widget(tlw) the window surface is created for. A QPlatformWindow is allways created + before the QWindowSurface for tlw where the widget also requires a WindowSurface. It is + possible to create top level QWidgets without a QWindowSurface by specifying + QPlatformWindowFormat::setWindowSurface(false) for the tlw QPlatformWindowFormat. + + \sa QWindowSurface + \sa createPlatformWindow(QWidget *widget, WId winId = 0) const +*/ + +/*! + \fn void moveToScreen(QWidget *window, int screen) + + This function is called when a QWidget is displayed on screen, or the QWidget is to be + displayed on a new screen. The QWidget parameter is a pointer to the top level widget and + the int parameter is the index to the screen in QList screens() const. + + Default implementation does nothing. + + \sa screens() const +*/ + +/*! + \fn QList screens() const + + Accessor function to a list of all the screens on the current system. The screen with the + index == 0 is the default/main screen. +*/ + +/*! + \fn bool isVirtualDesktop() + + Returns if the current windowing system configuration defines all the screens to be one + desktop(virtual desktop), or if each screen is a desktop of its own. + + Default implementation returns false. +*/ + +/*! + \fn QPixmap grabWindow(WId window, int x, int y, int width, int height) const + + This function is called when Qt needs to be able to grab the content of a window. + + Returnes the content of the window specified with the WId handle within the boundaries of + QRect(x,y,width,height). +*/ + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h index b1f4e5f..f01b4f4 100644 --- a/src/gui/kernel/qplatformintegration_qpa.h +++ b/src/gui/kernel/qplatformintegration_qpa.h @@ -69,10 +69,10 @@ public: virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0; virtual QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const = 0; virtual QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const = 0; - virtual void moveToScreen(QWidget *window, int screen) {Q_UNUSED(window); Q_UNUSED(screen);} // Window System functions virtual QList screens() const = 0; + virtual void moveToScreen(QWidget *window, int screen) {Q_UNUSED(window); Q_UNUSED(screen);} virtual bool isVirtualDesktop() { return false; } virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const; diff --git a/src/gui/kernel/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp index 478d2d6..5e80ba8 100644 --- a/src/gui/kernel/qplatformscreen_qpa.cpp +++ b/src/gui/kernel/qplatformscreen_qpa.cpp @@ -43,6 +43,12 @@ #include #include +/*! + Return the given top level widget for a given position. + + Default implementation retrieves a list of all top level widgets and finds the first widget + which contains point \a pos +*/ QWidget *QPlatformScreen::topLevelAt(const QPoint & pos) const { QWidgetList list = QApplication::topLevelWidgets(); @@ -56,6 +62,13 @@ QWidget *QPlatformScreen::topLevelAt(const QPoint & pos) const return 0; } +/*! \fn physicalSize() const + Reimplement in subclass to return the physical size of the screen. This function is used by + QFont to convert point sizes to pixel sizes. + + Default implementation takes the pixel size of the screen, considers a dpi of 100 and returns + the calculated (and probably wrong) physical size +*/ QSize QPlatformScreen::physicalSize() const { static const int dpi = 100; @@ -64,3 +77,38 @@ QSize QPlatformScreen::physicalSize() const return QSize(width,height); } +/*! + \class QPlatformScreen + \since 4.8 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformScreen class provides an abstraction for visual displays. + + Many window systems has support for retrieving information on the attached displays. To be able + to query the display QPA uses QPlatformScreen. Qt its self is most dependent on the + physicalSize() function, since this is the function it uses to calculate the dpi to use when + converting point sizes to pixels sizes. However, this is unfortunate on some systems, as the + native system fakes its dpi size. + + QPlatformScreen is also used by the public api QDesktopWidget for information about the desktop. + */ + +/*! \fn geometry() const + Reimplement in subclass to return the pixel geometry of the screen +*/ + +/*! \fn availableGeometry() const + Reimplement in subclass to return the pixel geometry of the available space + This normally is the desktop screen minus the task manager, global menubar etc. +*/ + +/*! \fn depth() const + Reimplement in subclass to return current depth of the screen +*/ + +/*! \fn format() const + Reimplement in subclass to return the image format which corresponds to the screen format +*/ + diff --git a/src/gui/kernel/qplatformscreen_qpa.h b/src/gui/kernel/qplatformscreen_qpa.h index 1704f0f..9080489 100644 --- a/src/gui/kernel/qplatformscreen_qpa.h +++ b/src/gui/kernel/qplatformscreen_qpa.h @@ -70,6 +70,7 @@ public: virtual int depth() const = 0; virtual QImage::Format format() const = 0; virtual QSize physicalSize() const; + //jl: should setDirty be removed. virtual void setDirty(const QRect &) {} virtual QWidget *topLevelAt(const QPoint &point) const; }; diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index 9d722d8..378fc68 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -51,6 +51,10 @@ class QPlatformWindowPrivate friend class QPlatformWindow; }; +/*! + Constructs a platform window with the given top level widget. +*/ + QPlatformWindow::QPlatformWindow(QWidget *tlw) : d_ptr(new QPlatformWindowPrivate) { @@ -59,22 +63,37 @@ QPlatformWindow::QPlatformWindow(QWidget *tlw) tlw->setPlatformWindow(this); } +/*! + Virtual destructor does not delete its top level widget. +*/ QPlatformWindow::~QPlatformWindow() { } +/*! + Returnes the widget which belongs to the QPlatformWindow +*/ QWidget *QPlatformWindow::widget() const { Q_D(const QPlatformWindow); return d->tlw; } +/*! + This function is called by Qt whenever a window is moved or the window is resized. The resize + can happen programatically(from ie. user application) or by the window manager. This means that + there is no need to call this function specifically from the window manager callback, instead + call QWindowSystemInterface::handleGeometryChange(QWidget *w, const QRect &newRect); +*/ void QPlatformWindow::setGeometry(const QRect &rect) { Q_D(QPlatformWindow); d->rect = rect; } +/*! + Returnes the current geometry of a window +*/ QRect QPlatformWindow::geometry() const { Q_D(const QPlatformWindow); @@ -82,14 +101,16 @@ QRect QPlatformWindow::geometry() const } /*! -Reimplemented in subclasses to show the surface if \a visible is \c true, and hide it if \a visible is \c false. + Reimplemented in subclasses to show the surface + if \a visible is \c true, and hide it if \a visible is \c false. */ void QPlatformWindow::setVisible(bool visible) { Q_UNUSED(visible); } /*! -Requests setting the window flags of this surface to \a type. Returns the actual flags set. + Requests setting the window flags of this surface + to \a type. Returns the actual flags set. */ Qt::WindowFlags QPlatformWindow::setWindowFlags(Qt::WindowFlags flags) { @@ -107,23 +128,83 @@ Qt::WindowFlags QPlatformWindow::windowFlags() const return d->flags; } +/*! + Reimplement in subclasses to return a handle to the native window +*/ WId QPlatformWindow::winId() const { return WId(0); } -void QPlatformWindow::setParent(const QPlatformWindow *) { qWarning("This plugin does not support setParent!"); } +/*! + This function is called to enable native child widgets in QPA. It is common not to support this + feature in Window systems, but can be faked. When this function is called all geometry of this + platform window will be relative to the parent. +*/ +//jl: It would be usefull to have a property on the platform window which indicated if the sub-class +// supported the setParent. If not, then geometry would be in screen coordinates. +void QPlatformWindow::setParent(const QPlatformWindow *parent) +{ + Q_UNUSED(parent); + qWarning("This plugin does not support setParent!"); +} -void QPlatformWindow::setWindowTitle(const QString &) {} +/*! + Reimplement to set the window title to \a title +*/ +void QPlatformWindow::setWindowTitle(const QString &title) {} +/*! + Reimplement to be able to let Qt rais windows to the top of the desktop +*/ void QPlatformWindow::raise() { qWarning("This plugin does not support raise()"); } +/*! + Reimplement to be able to let Qt lower winows to the bottom of the dekstop +*/ void QPlatformWindow::lower() { qWarning("This plugin does not support lower()"); } +/*! + Reimplement to be able to let Qt set the opacity level of a window +*/ void QPlatformWindow::setOpacity(qreal level) { Q_UNUSED(level); qWarning("This plugin does not support setting window opacity"); } +/*! + Reimplement to return the glContext assosiated with the window. +*/ QPlatformGLContext *QPlatformWindow::glContext() const { return 0; } + +/*! + \class QPlatformWindow + \since 4.8 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformWindow class provides an abstraction for top-level windows. + + The QPlatformWindow abstraction is used by QWidget for all its top level widgets. It is being + created by calling the createPlatformWindow function in the loaded QPlatformIntegration + instance. + + QPlatformWindow is used to signal to the windowing system, how Qt persieves its frame. + However, it is not concerned with how Qt renders into the window it represents. + + Top level QWidgets(tlw) will allways have a QPlatformWindow. However, it is not neccesary for + all tlw to have a QWindowSurface. This is the case for QGLWidget. And could be the case for + widgets where some 3.party renders into it. + + The platform specific window handle can be retrieved by the winId function. + + QPlatformWindow is also the way QPA defines how native child windows should be supported + through the setParent function. + + The only way to retrieve a QPlatformGLContext in QPA is by calling the glContext() function + on QPlatformWindow. + + \sa QWindowSurface, QWidget +*/ diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h index 6dfba05..90bc1cb 100644 --- a/src/gui/kernel/qplatformwindow_qpa.h +++ b/src/gui/kernel/qplatformwindow_qpa.h @@ -75,7 +75,7 @@ public: virtual WId winId() const; virtual void setParent(const QPlatformWindow *window); - virtual void setWindowTitle(const QString &); + virtual void setWindowTitle(const QString &title); virtual void raise(); virtual void lower(); diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp index f0dad17..ade6bb3 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.cpp +++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp @@ -102,9 +102,15 @@ public: /*! \class QPlatformWindowFormat \brief The QPlatformWindowFormat class specifies the display format of an OpenGL - rendering context. + rendering context and if possible attributes of the corresponding QPlatformWindow. - \ingroup painting-3D + \ingroup painting + + QWidget has a setter and getter function for QPlatformWindowFormat. These functions can be used + by the application programmer to signal what kind of format he wants to the window and glcontext + should have. However, it is not allways possible to furfill these requirements. The application + programmer should therefor check the resulting QPlatformWindowFormat from QPlatformGLContext + to see the format that was actually created. A display format has several characteristics: \list @@ -162,7 +168,7 @@ public: United States and other countries. \endlegalese - \sa QGLContext, QGLWidget + \sa QPlatformContext, QWidget */ /*! diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp index e9eb9c5..3ee8281 100644 --- a/src/gui/painting/qwindowsurface.cpp +++ b/src/gui/painting/qwindowsurface.cpp @@ -74,7 +74,7 @@ public: \since 4.3 \internal \preliminary - \ingroup qws + \ingroup qws qpa \brief The QWindowSurface class provides the drawing area for top-level windows. @@ -179,11 +179,20 @@ QRect QWindowSurface::geometry() const return d_ptr->geometry; } #else + +/*! + Sets the size of the windowsurface to be \a size. + + \sa size() +*/ void QWindowSurface::resize(const QSize &size) { d_ptr->size = size; } +/*! + Returns the current size of the windowsurface. +*/ QSize QWindowSurface::size() const { return d_ptr->size; diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 7a89fe4..d6dff41 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -165,6 +165,23 @@ bool QSupportedWritingSystems::supported(QFontDatabase::WritingSystem writingSys return d->vector.at(writingSystem); } +/*! + \class QSupportedWritingSystems + \brief The QSupportedWritingSystems class is used when registering fonts with the internal Qt + fontdatabase + \ingroup painting + + Its to provide an easy to use interface for indicating what writing systems a specific font + supports. + +*/ + +/*! + This function is called once at startup by Qts internal fontdatabase. Reimplement this function + in a subclass for a convenient place to initialise the internal fontdatabase. + + The default implementation looks in the fontDir() location and registers all qpf2 fonts. +*/ void QPlatformFontDatabase::populateFontDatabase() { QString fontpath = fontDir(); @@ -188,6 +205,9 @@ void QPlatformFontDatabase::populateFontDatabase() } } +/*! + +*/ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle) { Q_UNUSED(script); @@ -198,6 +218,9 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode return engine; } +/*! + +*/ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const { Q_UNUSED(family); @@ -219,12 +242,18 @@ QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData return QStringList(); } +/*! + +*/ void QPlatformFontDatabase::releaseHandle(void *handle) { QByteArray *fileDataPtr = static_cast(handle); delete fileDataPtr; } +/*! + +*/ QString QPlatformFontDatabase::fontDir() const { QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QPA_FONTDIR")); @@ -238,4 +267,24 @@ QString QPlatformFontDatabase::fontDir() const return fontpath; } +/*! + \class QPlatformFontDatabase + \brief The QPlatformFontDatabase makes it possible to customize how fonts are picked up, and + and how they are rendered + + \ingroup painting + + QPlatformFontDatabase is the superclass which is intended to let platform implementations use + native font handling. + + Qt has its internal fontdatabase which it uses to pick up available fonts. To be able + to populate this database subclass this class, and reimplement populateFontDatabase(). + + Use the function registerFont to populate the internal fontdatabase. + + Sometimes a specified font does not have the required glyphs, then the fallbackForFamily + function is called. + + \sa QSupportedWritingSystems +*/ QT_END_NAMESPACE -- cgit v0.12 From f309a20b4177572282082b8c17ec9025b75a69b1 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 23 Nov 2010 07:38:08 +0100 Subject: Make EglFS plugin compile after changes to QPlatformEGLContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Jørgen Lind --- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 9a40b86..b9d1b17 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -189,7 +189,7 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) attribList[temp++] = 2; // GLES version 2 attribList[temp++] = EGL_NONE; - m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); + m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API, 0); // qWarning("Created platformcontext"); EGLint w,h; -- cgit v0.12 From 004cd14b84e3683cd92cf01061ee9688990f990c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 23 Nov 2010 15:34:09 +0100 Subject: Lighthouse: Fix QGLContext::currentContext for systems with limited resources. The example plugins EGLFS uses only 1 native context. Make sure that we only use this 1 context, and that we dont wrap it in many different QPlatformGLContexts or QGLContexts instanses. This change also removes the QPlatformWindow link which was made in the initial QPlatformGLContext change. Lighthouse has to support situations where a context isnt bound to a QPlatformWindow. Reviewed-by: gunnar --- src/gui/kernel/qplatformglcontext_qpa.cpp | 18 ++---- src/gui/kernel/qplatformglcontext_qpa.h | 4 +- src/opengl/qgl.cpp | 58 ++++++++++++++--- src/opengl/qgl.h | 5 ++ src/opengl/qgl_qpa.cpp | 20 +++--- .../eglconvenience/qeglplatformcontext.cpp | 4 +- .../platforms/eglconvenience/qeglplatformcontext.h | 2 +- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 72 +++++++++++++++++----- src/plugins/platforms/eglfs/qeglfsscreen.h | 11 ++-- .../platforms/eglfs/qeglfswindowsurface.cpp | 5 +- src/plugins/platforms/testlite/qglxintegration.cpp | 6 +- src/plugins/platforms/testlite/qglxintegration.h | 2 +- src/plugins/platforms/testlite/qtestlitewindow.cpp | 2 +- 13 files changed, 141 insertions(+), 68 deletions(-) diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp index a450b33..5d2faf1 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ b/src/gui/kernel/qplatformglcontext_qpa.cpp @@ -61,8 +61,8 @@ static QThreadStorage qplatformgl_context_storage; class QPlatformGLContextPrivate { public: - QPlatformGLContextPrivate(QPlatformWindow *platformWindow) - :qGLContextHandle(0),platformWindow(platformWindow) + QPlatformGLContextPrivate() + :qGLContextHandle(0) { } @@ -73,7 +73,6 @@ public: } void *qGLContextHandle; void (*qGLContextDeleteFunction)(void *handle); - QPlatformWindow *platformWindow; static QPlatformGLContext *staticSharedContext; static void setCurrentContext(QPlatformGLContext *context); @@ -96,15 +95,6 @@ void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context) } /*! - Returns the platformWindow which this QPlatformGLContext belongs to. -*/ -QPlatformWindow *QPlatformGLContext::platformWindow() const -{ - Q_D(const QPlatformGLContext); - return d->platformWindow; -} - -/*! Returns the last context which called makeCurrent. This function is thread aware. */ const QPlatformGLContext* QPlatformGLContext::currentContext() @@ -119,8 +109,8 @@ const QPlatformGLContext* QPlatformGLContext::currentContext() /*! All subclasses needs to specify the platformWindow. It can be a null window. */ -QPlatformGLContext::QPlatformGLContext(QPlatformWindow *platformWindow) - :d_ptr(new QPlatformGLContextPrivate(platformWindow)) +QPlatformGLContext::QPlatformGLContext() + :d_ptr(new QPlatformGLContextPrivate()) { } diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h index 3e10c2b..a70e046 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.h +++ b/src/gui/kernel/qplatformglcontext_qpa.h @@ -58,7 +58,7 @@ class Q_OPENGL_EXPORT QPlatformGLContext Q_DECLARE_PRIVATE(QPlatformGLContext); public: - explicit QPlatformGLContext(QPlatformWindow *platformWindow); + explicit QPlatformGLContext(); virtual ~QPlatformGLContext(); virtual void makeCurrent(); @@ -68,8 +68,6 @@ public: virtual QPlatformWindowFormat platformWindowFormat() const = 0; - QPlatformWindow *platformWindow() const; - const static QPlatformGLContext *currentContext(); const static QPlatformGLContext *defaultSharedContext(); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 65d3bbe..5eb4c16 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2095,6 +2095,14 @@ QGLContext::QGLContext(const QGLFormat &format) d->init(0, format); } +QGLContext::QGLContext(QPlatformGLContext *platformContext) + : d_ptr(new QGLContextPrivate(this)) +{ + Q_D(QGLContext); + d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat())); + d->platformContext = platformContext; +} + /*! Destroys the OpenGL context and frees its resources. */ @@ -3152,6 +3160,18 @@ void QGLContext::setDevice(QPaintDevice *pDev) } } +QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) +{ + if (!platformContext) + return 0; + if (platformContext->qGLContextHandle()) { + return reinterpret_cast(platformContext->qGLContextHandle()); + } + QGLContext *glContext = new QGLContext(platformContext); + glContext->create(); + return glContext; +} + /*! \fn bool QGLContext::isValid() const @@ -3304,11 +3324,16 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex bool QGLContext::create(const QGLContext* shareContext) { Q_D(QGLContext); +#ifdef Q_WS_QPA + if (!d->paintDevice && !d->platformContext) +#else if (!d->paintDevice) +#endif return false; + reset(); d->valid = chooseContext(shareContext); - if (d->valid && d->paintDevice->devType() == QInternal::Widget) { + if (d->valid && d->paintDevice && d->paintDevice->devType() == QInternal::Widget) { QWidgetPrivate *wd = qt_widget_private(static_cast(d->paintDevice)); wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer(); } @@ -3389,14 +3414,7 @@ const QGLContext* QGLContext::currentContext() { #ifdef Q_WS_QPA if (const QPlatformGLContext *threadContext = QPlatformGLContext::currentContext()) { - if (threadContext->qGLContextHandle()) { - return (const QGLContext *)threadContext->qGLContextHandle(); - } else { - QWidget *widget = threadContext->platformWindow()->widget(); - QGLContext *context = new QGLContext(QGLFormat::fromPlatformWindowFormat(threadContext->platformWindowFormat()),widget); - context->create(); //don't know how to pass in the sharecontext. (doesn't really matter though) - return context; - } + return QGLContext::fromPlatformGLContext(const_cast(threadContext)); } return 0; #else @@ -3781,7 +3799,18 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); setAutoFillBackground(true); // for compatibility +#ifdef Q_WS_QPA + setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat())); + winId(); // create window; + QGLContext *glContext = 0; + if (platformWindow()) + glContext = QGLContext::fromPlatformGLContext(platformWindow()->glContext()); + if (glContext){ + d->init(glContext,shareWidget); + } +#else d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget); +#endif } @@ -3821,7 +3850,18 @@ QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); setAutoFillBackground(true); // for compatibility +#ifdef Q_WS_QPA + setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat())); + winId(); // create window; + QGLContext *glContext = 0; + if (platformWindow()) + glContext = QGLContext::fromPlatformGLContext(platformWindow()->glContext()); + if (glContext){ + d->init(glContext,shareWidget); + } +#else d->init(new QGLContext(format, this), shareWidget); +#endif } /*! diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 1f864a3..f5e0bd7 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -383,6 +383,7 @@ public: static const QGLContext* currentContext(); + static QGLContext *fromPlatformGLContext(QPlatformGLContext *platformContext); protected: virtual bool chooseContext(const QGLContext* shareContext = 0); @@ -412,6 +413,10 @@ protected: static QGLContext* currentCtx; private: +#ifdef Q_WS_QPA + QGLContext(QPlatformGLContext *platformContext); +#endif + QScopedPointer d_ptr; friend class QGLPixelBuffer; diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 28bea83..e997704 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -129,7 +129,11 @@ void qDeleteQGLContext(void *handle) bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); - if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { + if (d->platformContext && !d->platformContext->qGLContextHandle()) { + d->platformContext->setQGLContextHandle(this,qDeleteQGLContext); + d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat()); + d->valid = true; + }else if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { d->valid = false; }else { QWidget *widget = static_cast(d->paintDevice); @@ -215,10 +219,9 @@ void QGLWidget::setContext(QGLContext *context, qWarning("QGLWidget::setContext: Cannot set null context"); return; } - if (!context->deviceIsPixmap() && context->device() != this) { - qWarning("QGLWidget::setContext: Context must refer to this widget"); - return; - } + + if (context->device() == 0) // a context may refere to more than 1 window. + context->setDevice(this); //but its better to point to 1 of them than none of them. QGLContext* oldcx = d->glcx; d->glcx = context; @@ -312,11 +315,8 @@ bool QGLWidget::event(QEvent *e) { Q_D(QGLWidget); if (e->type() == QEvent::WinIdChange) { - if (d->glcx->isValid()) { - if (QGLContext::currentContext() == d->glcx) - QGLContextPrivate::setCurrentContext(0); //Its not valid anymore - setContext(new QGLContext(d->glcx->requestedFormat(), this)); - + if (platformWindow()) { + d->glcx = QGLContext::fromPlatformGLContext(platformWindow()->glContext()); } } return QWidget::event(e); diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp index a169c35..c4adb6f 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp @@ -48,8 +48,8 @@ #include -QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow) - : QPlatformGLContext(platformWindow) +QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi) + : QPlatformGLContext() , m_eglDisplay(display) , m_eglSurface(surface) , m_eglApi(eglApi) diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h index 2c38aca..ae1a891 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h @@ -48,7 +48,7 @@ class QEGLPlatformContext : public QPlatformGLContext { public: - QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow); + QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi); ~QEGLPlatformContext(); void makeCurrent(); diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index b9d1b17..7abc492 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -87,7 +87,10 @@ static struct AttrInfo attrs[] = { #endif //QEGL_EXTRA_DEBUG QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) - : m_depth(32), m_format(QImage::Format_ARGB32_Premultiplied), m_platformContext(0) + : m_depth(32) + , m_format(QImage::Format_Invalid) + , m_platformContext(0) + , m_surface(0) { #ifdef QEGL_EXTRA_DEBUG qWarning("QEglScreen %p\n", this); @@ -116,7 +119,25 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) qWarning("Initialized display %d %d\n", major, minor); - QPlatformWindowFormat platformFormat; + int swapInterval = 1; + QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); + if (!swapIntervalString.isEmpty()) { + bool ok; + swapInterval = swapIntervalString.toInt(&ok); + if (!ok) + swapInterval = 1; + } + eglSwapInterval(m_dpy, swapInterval); +} + +void QEglFSScreen::createAndSetPlatformContext() const { + const_cast(this)->createAndSetPlatformContext(); +} + +void QEglFSScreen::createAndSetPlatformContext() +{ + QPlatformWindowFormat platformFormat = QPlatformWindowFormat::defaultFormat(); + platformFormat.setWindowApi(QPlatformWindowFormat::OpenGL); QByteArray depthString = qgetenv("QT_QPA_EGLFS_DEPTH"); @@ -132,23 +153,15 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) platformFormat.setRedBufferSize(8); platformFormat.setGreenBufferSize(8); platformFormat.setBlueBufferSize(8); + m_depth = 32; + m_format = QImage::Format_RGB32; } - if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty()) { platformFormat.setSampleBuffers(true); } - int swapInterval = 1; - QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); - if (!swapIntervalString.isEmpty()) { - bool ok; - swapInterval = swapIntervalString.toInt(&ok); - if (!ok) - swapInterval = 1; - } EGLConfig config = q_configFromQPlatformWindowFormat(m_dpy, platformFormat); - eglSwapInterval(display, swapInterval); EGLNativeWindowType eglWindow = 0; #ifdef Q_OPENKODE @@ -189,15 +202,42 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display) attribList[temp++] = 2; // GLES version 2 attribList[temp++] = EGL_NONE; - m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API, 0); - -// qWarning("Created platformcontext"); - EGLint w,h; + m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); + EGLint w,h; // screen size detection eglQuerySurface(m_dpy, m_surface, EGL_WIDTH, &w); eglQuerySurface(m_dpy, m_surface, EGL_HEIGHT, &h); m_geometry = QRect(0,0,w,h); + +} + +QRect QEglFSScreen::geometry() const +{ + if (m_geometry.isNull()) { + createAndSetPlatformContext(); + } + return m_geometry; +} + +int QEglFSScreen::depth() const +{ + return m_depth; +} + +QImage::Format QEglFSScreen::format() const +{ + if (m_format == QImage::Format_Invalid) + createAndSetPlatformContext(); + return m_format; +} +QPlatformGLContext *QEglFSScreen::platformContext() const +{ + if (!m_platformContext) { + QEglFSScreen *that = const_cast(this); + that->createAndSetPlatformContext(); + } + return m_platformContext; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 9ed1b04..bfbfa62 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -57,13 +57,16 @@ public: QEglFSScreen(EGLNativeDisplayType display); ~QEglFSScreen() {} - QRect geometry() const { return m_geometry; } - int depth() const { return m_depth; } - QImage::Format format() const { return m_format; } + QRect geometry() const; + int depth() const; + QImage::Format format() const; - QPlatformGLContext *platformContext() const { return m_platformContext; } + QPlatformGLContext *platformContext() const; private: + void createAndSetPlatformContext() const; + void createAndSetPlatformContext(); + QRect m_geometry; int m_depth; QImage::Format m_format; diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp index fcea4d3..ebc04bd 100644 --- a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp @@ -57,13 +57,10 @@ public: #ifdef QEGL_EXTRA_DEBUG qWarning("QEglPaintDevice %p, %p, %p",this, screen, widget); #endif - QGLFormat format; - m_context = new QGLContext(format, widget); - m_context->create(); } QSize size() const { return m_screen->geometry().size(); } - QGLContext* context() const { return m_context;} + QGLContext* context() const { return QGLContext::fromPlatformGLContext(m_screen->platformContext());} QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } diff --git a/src/plugins/platforms/testlite/qglxintegration.cpp b/src/plugins/platforms/testlite/qglxintegration.cpp index c35db9b..a4b7b69 100644 --- a/src/plugins/platforms/testlite/qglxintegration.cpp +++ b/src/plugins/platforms/testlite/qglxintegration.cpp @@ -235,8 +235,8 @@ QPlatformWindowFormat QGLXGLContext::reducePlatformWindowFormat(const QPlatformW return retFormat; } -QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format) - : QPlatformGLContext(platformWindow) +QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format) + : QPlatformGLContext() , m_xd(xd) , m_drawable((Drawable)window) , m_context(0) @@ -271,7 +271,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *plat } QGLXGLContext::QGLXGLContext(MyDisplay *display, Drawable drawable, GLXContext context) - : QPlatformGLContext(0), m_xd(display), m_drawable(drawable), m_context(context) + : QPlatformGLContext(), m_xd(display), m_drawable(drawable), m_context(context) { } diff --git a/src/plugins/platforms/testlite/qglxintegration.h b/src/plugins/platforms/testlite/qglxintegration.h index 432dec5..e17790e 100644 --- a/src/plugins/platforms/testlite/qglxintegration.h +++ b/src/plugins/platforms/testlite/qglxintegration.h @@ -58,7 +58,7 @@ class MyDisplay; class QGLXGLContext : public QPlatformGLContext { public: - QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format); + QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format); ~QGLXGLContext(); virtual void makeCurrent(); diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp index 0a6e1ff..b52aae9 100644 --- a/src/plugins/platforms/testlite/qtestlitewindow.cpp +++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp @@ -1021,7 +1021,7 @@ QPlatformGLContext *QTestLiteWindow::glContext() const if (!mGLContext) { QTestLiteWindow *that = const_cast(this); #ifndef QT_NO_OPENGL - that->mGLContext = new QGLXGLContext(x_window, xd, that,widget()->platformWindowFormat()); + that->mGLContext = new QGLXGLContext(x_window, xd,widget()->platformWindowFormat()); #endif } return mGLContext; -- cgit v0.12 From 896c51e4d41a7fee06a1601f1b25746f9f98be88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 26 Nov 2010 09:17:35 +0100 Subject: Move the Lighthouse specfic api into qpa_qpa.cpp and ifdef the functions in qgl.h --- src/opengl/qgl.cpp | 12 ------------ src/opengl/qgl.h | 2 ++ src/opengl/qgl_qpa.cpp | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 5eb4c16..111a3e4 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3160,18 +3160,6 @@ void QGLContext::setDevice(QPaintDevice *pDev) } } -QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) -{ - if (!platformContext) - return 0; - if (platformContext->qGLContextHandle()) { - return reinterpret_cast(platformContext->qGLContextHandle()); - } - QGLContext *glContext = new QGLContext(platformContext); - glContext->create(); - return glContext; -} - /*! \fn bool QGLContext::isValid() const diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index f5e0bd7..ff135fa 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -383,7 +383,9 @@ public: static const QGLContext* currentContext(); +#ifdef Q_WS_QPA static QGLContext *fromPlatformGLContext(QPlatformGLContext *platformContext); +#endif protected: virtual bool chooseContext(const QGLContext* shareContext = 0); diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index e997704..d45f246 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -360,4 +360,24 @@ void QGLWidget::setColormap(const QGLColormap & c) Q_UNUSED(c); } + +QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) +{ + if (!platformContext) + return 0; + if (platformContext->qGLContextHandle()) { + return reinterpret_cast(platformContext->qGLContextHandle()); + } + QGLContext *glContext = new QGLContext(platformContext); + //Dont call create on context. This can cause the platformFormat to be set on the widget, which + //will cause the platformWindow to be recreated. + glContext->d_func()->platformContext->setQGLContextHandle(glContext,qDeleteQGLContext); + QGLFormat format = QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat()); + glContext->d_func()->glFormat = format; + glContext->d_func()->valid = true; + + return glContext; +} + + QT_END_NAMESPACE -- cgit v0.12 From 71abe300263d9f6bcd6e061e889a58111c48f92a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 26 Nov 2010 15:59:30 +0100 Subject: Make QtOpenGL use shared contextexts on Lighthouse --- src/gui/kernel/qplatformglcontext_qpa.cpp | 6 ++++- src/gui/kernel/qwidget_qpa.cpp | 24 ++++++++++---------- src/opengl/qgl.cpp | 24 +++++++++++--------- src/opengl/qgl_qpa.cpp | 33 +++++++++++++++++++++------- src/opengl/qglpixmapfilter.cpp | 2 +- src/opengl/qpixmapdata_gl.cpp | 30 ++++++++++++------------- src/opengl/qwindowsurface_gl.cpp | 32 +++++++++++++++++++++++++-- src/opengl/qwindowsurface_gl_p.h | 4 ++++ src/plugins/platforms/eglfs/qeglfsscreen.cpp | 4 +++- 9 files changed, 110 insertions(+), 49 deletions(-) diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp index 5d2faf1..14bd718 100644 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ b/src/gui/kernel/qplatformglcontext_qpa.cpp @@ -180,7 +180,11 @@ void QPlatformGLContext::setQGLContextHandle(void *handle,void (*qGLContextDelet void QPlatformGLContext::deleteQGLContext() { Q_D(QPlatformGLContext); - d->qGLContextDeleteFunction(d->qGLContextHandle); + if (d->qGLContextDeleteFunction && d->qGLContextHandle) { + d->qGLContextDeleteFunction(d->qGLContextHandle); + d->qGLContextDeleteFunction = 0; + d->qGLContextHandle = 0; + } } /*! diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index aa6b3f8..1f2a764 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -98,10 +98,12 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } Q_ASSERT(platformWindow); - if (!surface && platformWindow && q->platformWindowFormat().hasWindowSurface()) { - surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId()); - } else { - q->setAttribute(Qt::WA_PaintOnScreen,true); + if (!surface ) { + if (platformWindow && q->platformWindowFormat().hasWindowSurface()) { + surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId()); + } else { + q->setAttribute(Qt::WA_PaintOnScreen,true); + } } data.window_flags = q->platformWindow()->setWindowFlags(data.window_flags); @@ -787,13 +789,13 @@ void QWidgetPrivate::createTLSysExtra() void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) { - if (extra->topextra->platformWindowFormat.windowApi() == QPlatformWindowFormat::OpenGL) { - //the toplevel might have a context with a "qglcontext assosiated with it. We need to - //delete the qglcontext before we delete the qplatformglcontext. - if (extra->topextra->platformWindow) { - if (QPlatformGLContext *context = extra->topextra->platformWindow->glContext()) { - context->deleteQGLContext(); - } + //the toplevel might have a context with a "qglcontext assosiated with it. We need to + //delete the qglcontext before we delete the qplatformglcontext. + //One unfortunate thing about this is that we potentially create a glContext just to + //delete it straight afterwards. + if (extra->topextra->platformWindow) { + if (QPlatformGLContext *context = extra->topextra->platformWindow->glContext()) { + context->deleteQGLContext(); } } delete extra->topextra->platformWindow; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 111a3e4..dc7a333 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2095,14 +2095,6 @@ QGLContext::QGLContext(const QGLFormat &format) d->init(0, format); } -QGLContext::QGLContext(QPlatformGLContext *platformContext) - : d_ptr(new QGLContextPrivate(this)) -{ - Q_D(QGLContext); - d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat())); - d->platformContext = platformContext; -} - /*! Destroys the OpenGL context and frees its resources. */ @@ -3788,7 +3780,13 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl setAttribute(Qt::WA_NoSystemBackground); setAutoFillBackground(true); // for compatibility #ifdef Q_WS_QPA - setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat())); + QPlatformWindowFormat platformFormat = QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat()); + platformFormat.setUseDefaultSharedContext(false); + if (shareWidget && shareWidget->d_func()->glcx) { + QPlatformGLContext *sharedPlatformContext = shareWidget->d_func()->glcx->d_func()->platformContext; + platformFormat.setSharedContext(sharedPlatformContext); + } + setPlatformWindowFormat(platformFormat); winId(); // create window; QGLContext *glContext = 0; if (platformWindow()) @@ -3839,7 +3837,13 @@ QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* setAttribute(Qt::WA_NoSystemBackground); setAutoFillBackground(true); // for compatibility #ifdef Q_WS_QPA - setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat())); + QPlatformWindowFormat platformFormat = QGLFormat::toPlatformWindowFormat(format); + platformFormat.setUseDefaultSharedContext(false); + if (shareWidget && shareWidget->d_func()->glcx) { + QPlatformGLContext *sharedPlatformContext = shareWidget->d_func()->glcx->d_func()->platformContext; + platformFormat.setSharedContext(sharedPlatformContext); + } + setPlatformWindowFormat(platformFormat); winId(); // create window; QGLContext *glContext = 0; if (platformWindow()) diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index d45f246..415e915 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -129,11 +129,7 @@ void qDeleteQGLContext(void *handle) bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); - if (d->platformContext && !d->platformContext->qGLContextHandle()) { - d->platformContext->setQGLContextHandle(this,qDeleteQGLContext); - d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat()); - d->valid = true; - }else if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { + if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { d->valid = false; }else { QWidget *widget = static_cast(d->paintDevice); @@ -157,6 +153,18 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) } } + if (d->valid) { + QPlatformGLContext *sharedPlatformGLContext = d->platformContext->platformWindowFormat().sharedGLContext(); + if (sharedPlatformGLContext) { + QGLContext *actualSharedContext = QGLContext::fromPlatformGLContext(sharedPlatformGLContext); + if (actualSharedContext == shareContext) { + d->sharing = true;//Will add combination in QGLContext::create + }else { + QGLContextGroup::addShare(this,actualSharedContext); + } + } + } + return d->valid; } @@ -173,13 +181,15 @@ void QGLContext::reset() d->transpColor = QColor(); d->initDone = false; QGLContextGroup::removeShare(this); + if (d->platformContext) { + d->platformContext->setQGLContextHandle(0,0); + } } void QGLContext::makeCurrent() { Q_D(QGLContext); d->platformContext->makeCurrent(); - QGLContextPrivate::setCurrentContext(this); if (!d->workaroundsCached) { d->workaroundsCached = true; @@ -195,7 +205,6 @@ void QGLContext::doneCurrent() { Q_D(QGLContext); d->platformContext->doneCurrent(); - QGLContextPrivate::setCurrentContext(0); } void QGLContext::swapBuffers() const @@ -279,6 +288,8 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) d->widget->setGeometry(0,0,3,3); QPlatformWindowFormat format = d->widget->platformWindowFormat(); format.setWindowApi(QPlatformWindowFormat::OpenGL); + format.setWindowSurface(false); + d->widget->setPlatformWindowFormat(format); d->widget->winId(); d->widget->platformWindow()->glContext()->makeCurrent(); @@ -360,6 +371,13 @@ void QGLWidget::setColormap(const QGLColormap & c) Q_UNUSED(c); } +QGLContext::QGLContext(QPlatformGLContext *platformContext) + : d_ptr(new QGLContextPrivate(this)) +{ + Q_D(QGLContext); + d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat())); + d->platformContext = platformContext; +} QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) { @@ -379,5 +397,4 @@ QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContex return glContext; } - QT_END_NAMESPACE diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 73d698c..6c20aae 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -125,7 +125,7 @@ protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const; }; -extern QGLWidget *qt_gl_share_widget(); +extern const QGLContext *qt_gl_share_context(); QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *prototype) { diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index cd7f0c2..1cf5bd7 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE -extern QGLWidget* qt_gl_share_widget(); +extern const QGLContext* qt_gl_share_context(); /*! \class QGLFramebufferObjectPool @@ -261,14 +261,14 @@ QGLPixmapData::QGLPixmapData(PixelType type) QGLPixmapData::~QGLPixmapData() { - QGLWidget *shareWidget = qt_gl_share_widget(); - if (!shareWidget) + const QGLContext *shareContext = qt_gl_share_context(); + if (!shareContext) return; delete m_engine; if (m_texture.id) { - QGLShareContextScope ctx(shareWidget->context()); + QGLShareContextScope ctx(shareContext); glDeleteTextures(1, &m_texture.id); } } @@ -288,7 +288,7 @@ bool QGLPixmapData::isValidContext(const QGLContext *ctx) const if (ctx == m_ctx) return true; - const QGLContext *share_ctx = qt_gl_share_widget()->context(); + const QGLContext *share_ctx = qt_gl_share_context(); return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx); } @@ -308,7 +308,7 @@ void QGLPixmapData::resize(int width, int height) d = pixelType() == QPixmapData::PixmapType ? 32 : 1; if (m_texture.id) { - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); glDeleteTextures(1, &m_texture.id); m_texture.id = 0; } @@ -325,7 +325,7 @@ void QGLPixmapData::ensureCreated() const m_dirty = false; - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); m_ctx = ctx; const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB; @@ -399,7 +399,7 @@ void QGLPixmapData::fromImage(const QImage &image, d = m_source.depth(); if (m_texture.id) { - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); glDeleteTextures(1, &m_texture.id); m_texture.id = 0; } @@ -420,7 +420,7 @@ bool QGLPixmapData::fromFile(const QString &filename, const char *format, resize(0, 0); data = file.readAll(); file.close(); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); QSize size = m_texture.bindCompressedTexture (data.constData(), data.size(), format); if (!size.isEmpty()) { @@ -446,7 +446,7 @@ bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format, const char *buf = reinterpret_cast(buffer); if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) { resize(0, 0); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); QSize size = m_texture.bindCompressedTexture(buf, int(len), format); if (!size.isEmpty()) { w = size.width(); @@ -479,7 +479,7 @@ void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect) const QGLPixmapData *other = static_cast(data); if (other->m_renderFbo) { - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); resize(rect.width(), rect.height()); m_hasAlpha = other->m_hasAlpha; @@ -593,7 +593,7 @@ QImage QGLPixmapData::toImage() const ensureCreated(); } - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QGLShareContextScope ctx(qt_gl_share_context()); glBindTexture(GL_TEXTURE_2D, m_texture.id); return qt_gl_read_texture(QSize(w, h), true, true); } @@ -617,7 +617,7 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const m_hasFillColor = false; - const QGLContext *share_ctx = qt_gl_share_widget()->context(); + const QGLContext *share_ctx = qt_gl_share_context(); QGLShareContextScope ctx(share_ctx); ensureCreated(); @@ -672,8 +672,8 @@ QPaintEngine* QGLPixmapData::paintEngine() const extern QGLWidget* qt_gl_share_widget(); if (!QGLContext::currentContext()) - qt_gl_share_widget()->makeCurrent(); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); + const_cast(qt_gl_share_context())->makeCurrent(); + QGLShareContextScope ctx(qt_gl_share_context()); QGLFramebufferObjectFormat format; format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 47f36dd..cd7558c 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -182,6 +182,7 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL) // QGLWindowSurface // +#ifndef Q_WS_QPA class QGLGlobalShareWidget { public: @@ -255,6 +256,23 @@ void qt_destroy_gl_share_widget() { _qt_gl_share_widget()->destroy(); } +#endif//Q_WS_QPA + +const QGLContext *qt_gl_share_context() +{ +#ifdef Q_WS_QPA + //make it possible to have an assesor to defaultSharedGLContext. + const QPlatformGLContext *platformContext = QPlatformGLContext::defaultSharedContext(); + if (!platformContext) + qDebug() << "Please implement a defaultSharedContext for your platformplugin"; + return QGLContext::fromPlatformGLContext(const_cast(platformContext)); +#else + QGLWidget *widget = qt_gl_share_widget(); + if (widget) + return widget->context(); + return 0; +#endif +} struct QGLWindowSurfacePrivate { @@ -336,10 +354,12 @@ QGLWindowSurface::~QGLWindowSurface() { if (d_ptr->ctx) glDeleteTextures(1, &d_ptr->tex_id); +#ifndef Q_WS_QPA // Dont delete the contexts. Destroying the window does that for us foreach(QGLContext **ctx, d_ptr->contexts) { delete *ctx; *ctx = 0; } +#endif delete d_ptr->pb; delete d_ptr->fbo; @@ -356,6 +376,7 @@ void QGLWindowSurface::deleted(QObject *object) d_ptr->fbo = 0; } +#ifndef Q_WS_QPA //no need to specifically delete the QGLContext as it will be deleted by QWidget QWidgetPrivate *widgetPrivate = widget->d_func(); if (widgetPrivate->extraData()) { union { QGLContext **ctxPtrPtr; void **voidPtrPtr; }; @@ -367,6 +388,7 @@ void QGLWindowSurface::deleted(QObject *object) d_ptr->contexts.removeAt(index); } } +#endif } } @@ -377,8 +399,14 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) if (widgetPrivate->extraData()->glContext) return; +#ifdef Q_WS_QPA + QGLContext *ctx = QGLContext::fromPlatformGLContext(widget->platformWindow()->glContext()); + if (!d_ptr->fbo && d_ptr->tried_fbo) + d_ptr->ctx = ctx; +#else QGLContext *ctx = new QGLContext(surfaceFormat, widget); ctx->create(qt_gl_share_widget()->context()); +#endif #ifndef QT_NO_EGL static bool checkedForNOKSwapRegion = false; @@ -816,7 +844,7 @@ void QGLWindowSurface::updateGeometry() { } } -#if !defined(QT_OPENGL_ES_2) +#if !defined(QT_OPENGL_ES_2) && !defined(Q_WS_QPA) //QPA doesn't support pixelbuffers if (d_ptr->destructive_swap_buffers && (d_ptr->pb || !d_ptr->tried_pb)) { d_ptr->tried_pb = true; @@ -855,7 +883,7 @@ void QGLWindowSurface::updateGeometry() { d_ptr->pb = 0; } } -#endif // !defined(QT_OPENGL_ES_2) +#endif // !defined(QT_OPENGL_ES_2) !defined(Q_WS_QPA) ctx->makeCurrent(); diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h index 4f4ec92..22bd5f0 100644 --- a/src/opengl/qwindowsurface_gl_p.h +++ b/src/opengl/qwindowsurface_gl_p.h @@ -66,8 +66,12 @@ class QRegion; class QWidget; struct QGLWindowSurfacePrivate; +#ifdef Q_WS_QPA +Q_OPENGL_EXPORT const QGLContext* qt_gl_share_context(); +#else Q_OPENGL_EXPORT QGLWidget* qt_gl_share_widget(); Q_OPENGL_EXPORT void qt_destroy_gl_share_widget(); +#endif class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice { diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 7abc492..cbe6210 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -202,7 +202,9 @@ void QEglFSScreen::createAndSetPlatformContext() attribList[temp++] = 2; // GLES version 2 attribList[temp++] = EGL_NONE; - m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); + QEGLPlatformContext *platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); + platformContext->makeDefaultSaredContext(); + m_platformContext = platformContext; EGLint w,h; // screen size detection eglQuerySurface(m_dpy, m_surface, EGL_WIDTH, &w); -- cgit v0.12 From f7d66442963e1380a4f2db3d24cb24aa9d5c63ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 26 Nov 2010 16:01:29 +0100 Subject: Make the openKODE use the new eventloopintegration api. And also make it work with the new GL functionality in Lighthouse --- .../openkode/qopenkodeeventloopintegration.cpp | 27 ++++++++++++++-------- .../openkode/qopenkodeeventloopintegration.h | 6 +++-- .../platforms/openkode/qopenkodeintegration.cpp | 2 +- src/plugins/platforms/openkode/qopenkodewindow.cpp | 3 +-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp index 73d874c..aefabf0 100644 --- a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp +++ b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.cpp @@ -79,7 +79,7 @@ void kdprocessevent( const KDEvent *event) qDebug() << "KD_EVENT_INPUT_KEY_ATX"; break; case QT_EVENT_WAKEUP_EVENTLOOP: -// qDebug() << "QT_EVENT_WAKEUP_EVENTLOOP"; + QPlatformEventLoopIntegration::processEvents(); break; default: break; @@ -90,25 +90,34 @@ void kdprocessevent( const KDEvent *event) } QOpenKODEEventLoopIntegration::QOpenKODEEventLoopIntegration() + : m_quit(false) { m_kdThread = kdThreadSelf(); kdInstallCallback(&kdprocessevent,QT_EVENT_WAKEUP_EVENTLOOP,this); } -void QOpenKODEEventLoopIntegration::processEvents(qint64 msec) +void QOpenKODEEventLoopIntegration::startEventLoop() { - if (msec == 0) - msec = -1; - const KDEvent *event = kdWaitEvent(msec*1000); - if (event) { - kdDefaultEvent(event); - while ((event = kdWaitEvent(0)) != 0) { + + while(!m_quit) { + qint64 msec = nextTimerEvent(); + const KDEvent *event = kdWaitEvent(msec); + if (event) { kdDefaultEvent(event); + while ((event = kdWaitEvent(0)) != 0) { + kdDefaultEvent(event); + } } + QPlatformEventLoopIntegration::processEvents(); } } -void QOpenKODEEventLoopIntegration::wakeup() +void QOpenKODEEventLoopIntegration::quitEventLoop() +{ + m_quit = true; +} + +void QOpenKODEEventLoopIntegration::qtNeedsToProcessEvents() { KDEvent *event = kdCreateEvent(); event->type = QT_EVENT_WAKEUP_EVENTLOOP; diff --git a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h index 61bd444..73b287f 100644 --- a/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h +++ b/src/plugins/platforms/openkode/qopenkodeeventloopintegration.h @@ -54,12 +54,14 @@ class QOpenKODEEventLoopIntegration : public QPlatformEventLoopIntegration { public: QOpenKODEEventLoopIntegration(); - void processEvents(qint64 msec); - void wakeup(); + void startEventLoop(); + void quitEventLoop(); + void qtNeedsToProcessEvents(); void processInputEvent(const KDEvent *event); private: + bool m_quit; KDThread *m_kdThread; }; diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.cpp b/src/plugins/platforms/openkode/qopenkodeintegration.cpp index 60be897..763e69e 100644 --- a/src/plugins/platforms/openkode/qopenkodeintegration.cpp +++ b/src/plugins/platforms/openkode/qopenkodeintegration.cpp @@ -207,7 +207,7 @@ QWindowSurface *QOpenKODEIntegration::createWindowSurface(QWidget *widget, WId) case QPlatformWindowFormat::OpenVG: // returnSurface = new QVGWindowSurface(widget); - break; +// break; default: returnSurface = new QGLWindowSurface(widget); diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp index 32517c6..91c6473 100644 --- a/src/plugins/platforms/openkode/qopenkodewindow.cpp +++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp @@ -160,7 +160,7 @@ QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw) m_eglContextAttrs.data(), surface, m_eglApi); m_platformGlContext->makeDefaultSaredContext(); } else { - m_platformGlContext = static_cast(QPlatformGLContext::defaultSharedContext()); + m_platformGlContext = const_cast(static_cast(QPlatformGLContext::defaultSharedContext())); kdDestroyWindow(m_kdWindow); m_kdWindow = 0; } @@ -209,7 +209,6 @@ void QOpenKODEWindow::setGeometry(const QRect &rect) //need to recreate context if (needToDeleteContext) { - qDebug() << "deleting context"; delete m_platformGlContext; QList screens = QApplicationPrivate::platformIntegration()->screens(); -- cgit v0.12 From 9ec7743776a8d444d29ae4439039beff39fee1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 1 Dec 2010 16:33:52 +0100 Subject: Restore patch that disappeared in merge e50e811461b54e07184af547f62aa44b3c5bb681 --- src/gui/text/qfontengine_coretext.mm | 4 ++-- src/gui/text/qfontengine_coretext_p.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 984531b..d270e1f 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -585,9 +585,9 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition return im; } -QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) +QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) { - QImage im = imageForGlyph(glyph, QFixed(), 0, false); + QImage im = imageForGlyph(glyph, subPixelPosition, 0, false); QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); QVector colors(256); diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index d86c153..f31c033 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -83,7 +83,7 @@ public: virtual FaceId faceId() const; virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); virtual qreal minRightBearing() const; virtual qreal minLeftBearing() const; -- cgit v0.12 From 5fcdba84a8546a31974e4e1ecfaf481e0b9921a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 1 Dec 2010 16:37:51 +0100 Subject: Fix spelling mistake in QEGLPlatformcontext Autocompletion and a hint of dyslexia made me not see this before :) Reviewed-by: paul --- src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp | 2 +- src/plugins/platforms/eglconvenience/qeglplatformcontext.h | 2 +- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 2 +- src/plugins/platforms/openkode/qopenkodewindow.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp index c4adb6f..4b83a22 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp @@ -146,7 +146,7 @@ void* QEGLPlatformContext::getProcAddress(const QString& procName) return (void *)eglGetProcAddress(qPrintable(procName)); } -void QEGLPlatformContext::makeDefaultSaredContext() +void QEGLPlatformContext::makeDefaultSharedContext() { setDefaultSharedContext(this); } diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h index ae1a891..ac53559 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h @@ -56,7 +56,7 @@ public: void swapBuffers(); void* getProcAddress(const QString& procName); - void makeDefaultSaredContext(); + void makeDefaultSharedContext(); QPlatformWindowFormat platformWindowFormat() const; private: diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index cbe6210..db90ff2 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -203,7 +203,7 @@ void QEglFSScreen::createAndSetPlatformContext() attribList[temp++] = EGL_NONE; QEGLPlatformContext *platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API); - platformContext->makeDefaultSaredContext(); + platformContext->makeDefaultSharedContext(); m_platformContext = platformContext; EGLint w,h; // screen size detection diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp index 91c6473..01f8d21 100644 --- a/src/plugins/platforms/openkode/qopenkodewindow.cpp +++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp @@ -158,7 +158,7 @@ QOpenKODEWindow::QOpenKODEWindow(QWidget *tlw) EGLSurface surface = eglCreateWindowSurface(screen->eglDisplay(),m_eglConfig,m_eglWindow,m_eglWindowAttrs.constData()); m_platformGlContext = new QEGLPlatformContext(screen->eglDisplay(), m_eglConfig, m_eglContextAttrs.data(), surface, m_eglApi); - m_platformGlContext->makeDefaultSaredContext(); + m_platformGlContext->makeDefaultSharedContext(); } else { m_platformGlContext = const_cast(static_cast(QPlatformGLContext::defaultSharedContext())); kdDestroyWindow(m_kdWindow); -- cgit v0.12 From c3f22e0b7ee6358ebe063b3aeea4a609e367a5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 1 Dec 2010 17:04:45 +0100 Subject: Spelling mistakes in Documentation. There are probably more :) Reviewed-by: paul --- src/gui/kernel/qplatformintegration_qpa.cpp | 6 +++--- src/gui/kernel/qplatformwindow_qpa.cpp | 8 ++++---- src/gui/kernel/qplatformwindowformat_qpa.cpp | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index 2a9bf77..9b6e590 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -68,7 +68,7 @@ QPlatformEventLoopIntegration *QPlatformIntegration::createEventLoopIntegration( } /*! - Returns wheter the given platform integration supports OpenGL. + Returns whether the given platform integration supports OpenGL. Default implementation returns false, */ @@ -103,7 +103,7 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const QPlatformIntegration is the single entry point for windowsystem specific functionality when using the QPA platform. It has factory functions for creating platform specific pixmaps and - windows. The class also controlls the font subsystem. + windows. The class also controls the font subsystem. QPlatformIntegration is a singelton class which gets instansiated in the QApplication constructor. The QPlatformIntegration instance do not have ownership of objects it creates in @@ -147,7 +147,7 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const \fn QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const Factory function for QWindowSurface. The QWidget parameter is a pointer to the - top level widget(tlw) the window surface is created for. A QPlatformWindow is allways created + top level widget(tlw) the window surface is created for. A QPlatformWindow is always created before the QWindowSurface for tlw where the widget also requires a WindowSurface. It is possible to create top level QWidgets without a QWindowSurface by specifying QPlatformWindowFormat::setWindowSurface(false) for the tlw QPlatformWindowFormat. diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index 378fc68..29eaa82 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -138,7 +138,7 @@ WId QPlatformWindow::winId() const { return WId(0); } feature in Window systems, but can be faked. When this function is called all geometry of this platform window will be relative to the parent. */ -//jl: It would be usefull to have a property on the platform window which indicated if the sub-class +//jl: It would be useful to have a property on the platform window which indicated if the sub-class // supported the setParent. If not, then geometry would be in screen coordinates. void QPlatformWindow::setParent(const QPlatformWindow *parent) { @@ -157,7 +157,7 @@ void QPlatformWindow::setWindowTitle(const QString &title) {} void QPlatformWindow::raise() { qWarning("This plugin does not support raise()"); } /*! - Reimplement to be able to let Qt lower winows to the bottom of the dekstop + Reimplement to be able to let Qt lower windows to the bottom of the desktop */ void QPlatformWindow::lower() { qWarning("This plugin does not support lower()"); } @@ -171,7 +171,7 @@ void QPlatformWindow::setOpacity(qreal level) } /*! - Reimplement to return the glContext assosiated with the window. + Reimplement to return the glContext associated with the window. */ QPlatformGLContext *QPlatformWindow::glContext() const { @@ -194,7 +194,7 @@ QPlatformGLContext *QPlatformWindow::glContext() const QPlatformWindow is used to signal to the windowing system, how Qt persieves its frame. However, it is not concerned with how Qt renders into the window it represents. - Top level QWidgets(tlw) will allways have a QPlatformWindow. However, it is not neccesary for + Top level QWidgets(tlw) will always have a QPlatformWindow. However, it is not necessary for all tlw to have a QWindowSurface. This is the case for QGLWidget. And could be the case for widgets where some 3.party renders into it. diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp index ade6bb3..44b0698 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.cpp +++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp @@ -108,8 +108,8 @@ public: QWidget has a setter and getter function for QPlatformWindowFormat. These functions can be used by the application programmer to signal what kind of format he wants to the window and glcontext - should have. However, it is not allways possible to furfill these requirements. The application - programmer should therefor check the resulting QPlatformWindowFormat from QPlatformGLContext + should have. However, it is not always possible to fulfill these requirements. The application + programmer should therefore check the resulting QPlatformWindowFormat from QPlatformGLContext to see the format that was actually created. A display format has several characteristics: @@ -639,7 +639,7 @@ QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const otherwise the QWidget will only have a QPlatformWindow. - This is usefull for ie. QGLWidget where the QPlatformGLContext controlls the surface. + This is useful for ie. QGLWidget where the QPlatformGLContext controls the surface. \sa hasOverlay() */ -- cgit v0.12 From 34f199a1267ea923df33690b50920ef3383b85c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 2 Dec 2010 08:38:49 +0100 Subject: Fix spelling in comment --- src/gui/kernel/qwidget_qpa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index 1f2a764..617d984 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -789,7 +789,7 @@ void QWidgetPrivate::createTLSysExtra() void QWidgetPrivate::deleteTLSysExtra() { if (extra && extra->topextra) { - //the toplevel might have a context with a "qglcontext assosiated with it. We need to + //the toplevel might have a context with a "qglcontext associated with it. We need to //delete the qglcontext before we delete the qplatformglcontext. //One unfortunate thing about this is that we potentially create a glContext just to //delete it straight afterwards. -- cgit v0.12 From 697f2f96eccaaf9feb2f6e92603e86e30e67cdb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 2 Dec 2010 11:07:59 +0100 Subject: Restore patch that got lost in merge The merge was: e50e811461b54e07184af547f62aa44b3c5bb681 The parts of these commits was lost in the manual merge: 46d2d05e3a95eefae1c72f55d57cbea4ce27d14e 8e8bae1f4faf676b6104bbf9039ad10f139fa7e8 344a4dcfe847dd778c33d1a852381672dd331409 e45c4387ae16627d61e30a58ae901d888d375aa7 And I also added a license header to qfontengine_coretext.mm Reviewed-by: paul --- src/gui/text/qfontengine_coretext.mm | 67 +++++++++++++++++++++++++++++++++-- src/gui/text/qfontengine_coretext_p.h | 2 +- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index d270e1f..dcc8329 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "qfontengine_coretext_p.h" #include @@ -7,6 +48,8 @@ #if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) +QT_BEGIN_NAMESPACE + QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning) : QFontEngineMulti(0) { @@ -117,6 +160,11 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay continue; Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl); + CFRange stringRange = CTRunGetStringRange(run); + UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1); + bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF; + if (endWithPDF) + glyphCount++; if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) { outOBounds = true; @@ -129,6 +177,9 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CTFontRef runFont = static_cast(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); const uint fontIndex = (fontIndexForFont(runFont) << 24); //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); + if (endWithPDF) + glyphCount--; + QVarLengthArray cgglyphs(0); const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); if (!tmpGlyphs) { @@ -196,6 +247,16 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay (fontDef.styleStrategy & QFont::ForceIntegerMetrics) ? QFixed::fromReal(lastGlyphAdvance.width).round() : QFixed::fromReal(lastGlyphAdvance.width); + + if (endWithPDF) { + logClusters[stringRange.location + stringRange.length - 1] = glyphCount; + outGlyphs[glyphCount] = 0xFFFF; + outAdvances_x[glyphCount] = 0; + outAdvances_y[glyphCount] = 0; + outAttributes[glyphCount].clusterStart = true; + outAttributes[glyphCount].dontPrint = true; + glyphCount++; + } } outGlyphs += glyphCount; outAttributes += glyphCount; @@ -566,7 +627,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CGContextSetFont(ctx, cgFont); qreal pos_x = -br.x.toReal() + subPixelPosition.toReal(); - qreal pos_y = im.height()+br.y.toReal(); + qreal pos_y = im.height() + br.y.toReal() - 1; CGContextSetTextPosition(ctx, pos_x, pos_y); CGSize advance; @@ -585,7 +646,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition return im; } -QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) +QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) { QImage im = imageForGlyph(glyph, subPixelPosition, 0, false); @@ -663,5 +724,7 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metric // ### } +QT_END_NAMESPACE + #endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index f31c033..b4450fa 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -83,7 +83,7 @@ public: virtual FaceId faceId() const; virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); - virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); + virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); virtual qreal minRightBearing() const; virtual qreal minLeftBearing() const; -- cgit v0.12