summaryrefslogtreecommitdiffstats
path: root/src/openvg
Commit message (Collapse)AuthorAgeFilesLines
* Use QImage 'convertInPlace' versions in QVGPixmapData load functions.Jani Hautakangas2010-08-242-1/+60
| | | | | | | QImage 'convertInPlace' uses less memory than 'convertToFormat' version. Task-number: QT-3710 Reviewed-by: Jason Barron
* Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Thiago Macieira2010-08-111-6/+20
|\ | | | | | | | | | | | | | | Conflicts: src/gui/kernel/qt_s60_p.h src/opengl/qglextensions.cpp src/opengl/qglshaderprogram.cpp tests/auto/mediaobject/tst_mediaobject.cpp
| * Improving text coordinate rounding in the OpenVG paint engineAlessandro Portale2010-08-041-3/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit b0bbabe728fedb8531fc2837403856bd5ed44e1b fixed text blurriness in the OpenVG paint engine by forcing the coordinates of the text items to integer coordinates (for unrotated, unscaled text). That was not yet enough. In addition to the coordinates, also the d->pathTransform in QVGPaintEngine can have a non-integer translation. This patch makes sure that the text item coordinate combined with the translation result in final integer coordinates. Since it is not possible to set an absolute translation of a QTransform (only relative is possible), first dx() is added to p.x(), then after rounding, it is again substracted. Sam for y, but with opposite prefix, since the y-axis in Qt and in transformation matrices are in opposite directions. The ceil stunt (which I cerated by trial and error) was replaced by floor(x + aliasedCoordinateDelta), which *exactly* what other paint engines do. Task-number: QTBUG-12330 Reviewed-by: Jason Barron
| * Fix proxy widgets with the OpenVG paint engine.Jason Barron2010-07-301-3/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Proxy widgets use the shared painter functionality and this implies that the paint engine's begin function does not get called for each new widget that gets painted. This causes a problem because the system clip gets modified by QPainter, but the paint engine does not realize that this happened and fails to use the new clip. The result is that you can end up painting outside the intended clip area. The fix is to reimplement the virtual systemStateChanged() function in QVGPaintEnginePrivate and make it call updateScissor() to re-evaluate the clipping flags and update the current clip accordingly. A similar fix was done to the OpenGL paint engine way back in 307c2954. Task-number: QTBUG-12486 Reviewed-by: Rhys Weatherley
* | Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Thiago Macieira2010-07-151-2/+12
|\ \ | |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: bin/syncqt src/3rdparty/webkit/VERSION src/3rdparty/webkit/WebCore/ChangeLog src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.h src/3rdparty/webkit/WebCore/page/FrameView.cpp src/3rdparty/webkit/WebCore/page/FrameView.h src/3rdparty/webkit/WebCore/platform/ScrollView.cpp src/3rdparty/webkit/WebCore/platform/ScrollView.h src/corelib/plugin/quuid.cpp src/gui/dialogs/qfontdialog.cpp src/multimedia/audio/qaudiodevicefactory.cpp src/opengl/qgl.cpp src/openvg/qpaintengine_vg.cpp tests/auto/qxmlquery/tst_qxmlquery.cpp
| * Avoid a crash in the OpenVG paint engine when clipping to an empty pathJason Barron2010-07-151-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The convertToPainterPath() function assumes that the QVectorPath contains at least one path element when creating the QPainterPath. This is not necessarily the case here though because if QVG_SCISSOR_CLIP is defined and setClipPath() is called with an empty QPainterPath, this is then converted to an empty QVectorPath in QPaintEngineEx::clip() which then calls QVGPaintEngine::clip(). This function then goes on to convert the QVectorPath back into a QPainterPath using the aforementioned function which crashes when attempting to access the first element of the path. In case you are wondering why this seemingly redundant conversion happens at all, it happens because when QVG_SCISSOR_CLIP is defined, we attempt to convert the path to a series of rects for scissor clipping and this conversion function operates on QPainterPath instead of QVectorPath which is what this clip() function was designed to deal with. The fix is to skip over the path conversion for empty paths and go directly to an empty QRegion. Reviewed-by: Alessandro Portale
| * Include qmath.h to get the definition of ceil()Rhys Weatherley2010-07-051-0/+1
| | | | | | | | Reviewed-by: Julian de Bhal
| * Avoid blurry text with OpenVG on SymbianAlessandro Portale2010-06-301-1/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Qt's graphics system uses qreal as measurement unit. The established paint engines (such as "raster") implicitly round textitem coordinates for technical reasons, e.g. for optimized blitting. Some Qt based Ui libraries (such as QWidgets) can in some cases cause textitems to be drawn on non-integer coordinates. In particular, this happens when centering text. Since these libraries have been developed against the established paint engines with implicit rounding, these non-integer coordinates were never an issue. The new OpenVG paintengine took these coordinates seriously without rounding them. On some OpenVG implementations (e.g. that of some Symbian phones), this led to blurry text rendering. This patch adds coordinate rounding for unscaled, unrotated textitems to the OpenVG paintengine. So that it does the same as the raster paint engine. Task-number: QT-3071 Reviewed-By: Jason Barron
* | Minor modifications and optimizations to the Symbian HW glyph cache.Jason Barron2010-07-121-49/+60
| | | | | | | | | | | | | | | | | | | | | | | | After the latest round of API reviews, the Symbian glyph cache has now been moved from GDI to FBS and this required some changes in Qt's implementation. Also incorporate an optimization where we first iterate over the glyph vector to eliminate glyphs that are already cached in Qt's glyph cache. This way we only open the glyph iterator on glyphs that we need. Reviewed-by: Alessandro Portale
* | Convert to new EGL API.Jason Barron2010-07-122-47/+42
| | | | | | | | | | | | | | Recent changes in Qt's EGL layer required some changes in the code used to convert RSgImage to/from VGImage. Reviewed-by: Gunnar Sletta
* | Don't invert glyphs for the default VG font cache on Symbian.Jason Barron2010-07-121-0/+2
| | | | | | | | | | | | | | If the hardware glyph cache API is not represent and in use, then the glyphs will not be inverted. Reviewed-by: TrustMe
* | Move QVGFontGlyphCache from source file into a separate headerJason Barron2010-07-121-1/+0
| | | | | | | | | | | | | | Needed in order to subclass and override in the Symbian specific implementation. Reviewed-by: Rhys Weatherley
* | Ensure glyphs are upright instead of upside-down.Jason Barron2010-07-123-1/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The OpenVG paint engine traditionally takes glyph images from the alphaMapForGlyph() function which returns the glyph image in the upright projection. When it constructs a VGImage from this image, it passes a positive data stride which will read the top scanline of the source image into the bottom scanline of the VGImage due to the VG coordinate system. It then uses the path transform where the 'sy' value of the matrix is set to -1 and this re-inverts everything when drawing. With the Symbian based glyph cache, the VGImage is constructed from a RSgImage which is a hardware resource and compensates for the coordinate system used by VG and GL at the time it is created. In the case of the hardware glyph cache, the glyph image is read into the RSgImage using a negative data stride so it does not need to be inverted when drawn. To allow for this, introduce a flag which indicates that the 'sy' entry of the matrix should be flipped such that the glyph is drawn normally. Also in this patch is a change to the glyph origin which now uses the bottom of the glyph metric bounding rect instead of the top due to orientation of the glyph inside the VGImage. Reviewed-by: Alessandro Portale
* | Enable cross-process glyph cache for OpenVG graphics system on Symbian.Jason Barron2010-07-123-21/+60
| | | | | | | | | | | | | | | | | | | | | | This introduces a specialized OpenVG font cache for the Symbian platform. By using RGlyphDataIterator we can create a VGImage to store inside a VGFont without having to upload our own glyph image. This works by utilizing RSgImage which can be used to share handles to graphics memory across processes thus allowing glyph images to be shared by multiple processes and reducing graphics memory usage. Reviewed-by: Alessandro Portale
* | Factor out RSgImage -> VGImage conversion to separate function.Jason Barron2010-07-121-73/+75
| | | | | | | | | | | | | | | | | | | | This code will now be used by both the fromNativeType() function and the upcoming glyph cache implementation. We also change the #ifdef's location here slightly because even if we do not have support for RSgImage, we still want to be able to support the CFbsBitmap conversion functions for the OpenVG graphics system. Reviewed-by: Alessandro Portale
* | Add new file for Symbian specific VG stuff and add Symbian glyph cache.Jason Barron2010-07-124-260/+362
| | | | | | | | | | | | | | | | | | Factor out the Symbian specific bits of QVGPixmapData into a separate file and introduce our subclassed implementation of the VG font cache. Also make our font cache a friend of the S60 font engine because the cache needs to access the CFont member to create the glyph image. Reviewed-by: Alessandro Portale
* | Move QVGFontGlyphCache from source file into a separate headerJason Barron2010-07-124-20/+87
| | | | | | | | | | | | | | Needed in order to subclass and override in the Symbian specific implementation. Reviewed-by: Rhys Weatherley
* | Make cacheGlyphs() function (and the destructor) virtual.Jason Barron2010-07-121-2/+2
| | | | | | | | | | | | | | | | This class will be implemented differently on Symbian due to the presence of a class that allows cross process sharing of glyph images so make this function virtual. Reviewed-by: Rhys Weatherley
* | Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Olivier Goffart2010-06-081-4/+41
|\ \ | |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/3rdparty/webkit/VERSION src/3rdparty/webkit/WebCore/ChangeLog src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp src/3rdparty/webkit/WebKit/qt/ChangeLog src/gui/painting/qpainter.cpp src/gui/painting/qtextureglyphcache.cpp src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h src/s60installs/bwins/QtGuiu.def src/s60installs/eabi/QtCoreu.def src/s60installs/eabi/QtGuiu.def src/s60installs/eabi/QtNetworku.def src/s60installs/eabi/QtOpenVGu.def tests/auto/qfontmetrics/tst_qfontmetrics.cpp tools/linguist/lupdate/main.cpp
| * Clipping with rounded rectangles and QVG_SCISSOR_CLIPRhys Weatherley2010-06-021-4/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | WebKit draws rounded rectangles by setting a rounded rect path as a clip and then filling the clip. This had problems when QVG_SCISSOR_CLIP was enabled because the scissor would only clip to the bounding box of complex paths. Thus, rounded rectangle clips were turned into normal rectangle clips. This change will make the scissor clipping code subdivide complex paths into rectangles and use a tighter clip if the number of rectangles is less than or equal to VG_MAX_SCISSOR_RECTS. If it is greater, then it will fall back to the bounding box of the path. Task-number: QT-3372 Reviewed-by: Jason Barron
* | Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Olivier Goffart2010-05-171-4/+83
|\ \ | |/ | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: demos/demos.pro mkspecs/features/resources.prf mkspecs/features/uic.prf src/corelib/io/qurl.cpp src/corelib/tools/qlocale_symbian.cpp src/gui/graphicsview/qgraphicsscene.cpp src/gui/graphicsview/qgraphicswidget_p.cpp src/gui/graphicsview/qgraphicswidget_p.h src/gui/util/qsystemtrayicon_win.cpp src/multimedia/audio/qaudioinput.cpp tests/auto/qhostinfo/qhostinfo.pro
| * OpenVG blending modes from VG_KHR_advanced_blending extensionRhys Weatherley2010-05-121-4/+83
| | | | | | | | | | | | | | | | | | | | This change introduces the extra blending modes that are defined in the VG_KHR_advanced_blending extension. Patch originally provided by contributor: http://qt.gitorious.org/qt/qt/merge_requests/505 Reviewed-by: Julian de Bhal
* | Apply Rhys's fix to qpaintengine_vg.cpp to make it compileThiago Macieira2010-04-272-6/+7
| |
* | Attempt again at fixing the OpenVG paint engine buildThiago Macieira2010-04-262-8/+11
| |
* | Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Thiago Macieira2010-04-221-32/+22
|\ \ | |/ | | | | | | Conflicts: src/openvg/qpaintengine_vg.cpp
| * correctly position glyphs for complex languagesLars Knoll2010-04-211-32/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | Correctly use the positions calculated by getGlyphPositions to draw the glyphs. Simplify the logic a bit so that we don't need the glyphTransform anymore, but can instead just use the pathTransform for text drawing as well. Tested with latin, arabic, hebrew and Hindi text Task-number: QT-3300 Reviewed-by: Jason Barron
* | Revert "Attempt at fixing compile failure introduced by 4.6 merge in ↵Thiago Macieira2010-04-222-4/+4
| | | | | | | | | | | | qpaintengine_vg.cpp" This reverts commit 27688a5e317f6602752eaea257ba46abbc9acf44.
* | Attempt at fixing compile failure introduced by 4.6 merge in qpaintengine_vg.cppThiago Macieira2010-04-222-4/+4
| |
* | Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Thiago Macieira2010-04-211-3/+7
|\ \ | |/ | | | | | | | | | | Conflicts: src/openvg/qpaintengine_vg.cpp src/script/bridge/qscriptqobject_p.h tests/auto/bic/tst_bic.cpp
| * Fix RTL text rendering in the QVGPaintEngineAlessandro Portale2010-04-161-2/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The QVGPaintEngine calls vgDrawGlyphs() to draw the glyphs of a QTextItem. vgDrawGlyphs(), which is an official OpenVG function, and not implemented in Qt itself, expects glyphs coordinates differently than Qt's glyph painting loops of other paint engines expect. Therefore, we need to handle RTL text separately in QVGPaintEngine::drawTextItem(). Rhys Weatherley provided this patch. This issue is not Symbian specific, but rather QVGPaintEngine specific. Task-number: QT-3140 Reviewed-by: Rhys Weatherley
* | Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into ↵Qt Continuous Integration System2010-04-171-15/+6
|\ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | 4.7-integration * '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: Some QWindowSurface implementations might implement flush as a buffer Set EGL_SWAP_BEHAVIOR to EGL_BUFFER_PRESERVED for regular QWidgets Cleanup & remove unused function overloads from QEgl* APIs QScrollArea: Excessive scrolling in focusNextPrevChild()
| * | Cleanup & remove unused function overloads from QEgl* APIsTom Cooksey2010-04-161-15/+6
| | | | | | | | | | | | | | | | | | This should make stubbing out these APIs slightly easier. Reviewed-By: TrustMe
* | | Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Olivier Goffart2010-04-166-8/+42
|\ \ \ | |/ / |/| / | |/ | | | | | | | | | | | | | | | | | | | | Conflicts: src/3rdparty/webkit/VERSION src/3rdparty/webkit/WebCore/ChangeLog src/3rdparty/webkit/WebCore/page/FrameView.cpp src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp src/3rdparty/webkit/WebKit/qt/symbian/eabi/QtWebKitu.def src/s60installs/bwins/QtCoreu.def src/s60installs/bwins/QtGuiu.def src/s60installs/bwins/QtNetworku.def src/s60installs/eabi/QtGuiu.def tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp
| * Symbol visibility fixes for RVCT4 on SymbianIain2010-04-152-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | RVCT 4 is far more strict with regards to symbol visiblity that RVCT 2.2, and will hide symbols unless all references have default visibility in the object files. Update the various places in Qt code where the symbol visibility was set incorrectly for DLL-based platforms (those that use __declspec(dllimport) and (dllexport). Note: QtWebkit and QtScript are fixed in different commits. Task-number: QTBUG-9903 Reviewed-by: Jason Barron
| * Implement OpenVG buffer scrolling and enable it on Symbian.Jason Barron2010-04-144-2/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add support for accelerated scrolling in the "direct" window surface implementation. Using vgCopyPixels(), the already rasterized content on the surface can be shifted to a new location such that only a portion of the suqsequent frame needs to be repainted instead of the entire frame. This only works when the "preserved" EGL swap behavior is enabled and the impact on performance is highly dependant on the specific hardware platform in use. Task-number: QT-2972 Reviewed-by: Rhys Weatherley
* | Wrap EGL image function pointers and move into QEgl namespaceTom Cooksey2010-04-151-6/+6
| | | | | | | | | | | | | | QtGui exporting a symbol called eglCreateImageKHR seems a pretty silly idea. Much better to have them in the QEgl namespace. Reviewed-By: Iain
* | Fix compilation of ShivaVG, which does not have EGL.Rhys Weatherley2010-04-151-0/+2
| | | | | | | | | | Task-number: QTBUG-9809 Reviewed-by: Sarah Smith
* | Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Thiago Macieira2010-04-121-11/+13
|\ \ | |/ | | | | | | | | | | Conflicts: qmake/generators/symbian/symmake.cpp src/gui/image/qimage.cpp src/openvg/qwindowsurface_vgegl.cpp
| * Enable preserved swap behavior when surface is created due to resize.Jason Barron2010-04-091-11/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When the QVG_RECREATE_ON_SIZE_CHANGE macro is defined the EGL surface is recreated. However, after creating the surface, we were neglecting to set the surface attribute that enabled the preserved swapping behavior of EGL. This lead to flicker because every second frame was swapping with an empty buffer and only the dirty areas were being painted leaving the rest empty. Reviewed-by: Lars Knoll Reviewed-by: Aleksandar Sasha Babic Task-number: QT-3198 Task-number: QT-3184 Task-number: QT-3201
* | Merge remote branch 'integration/qt-4.7-from-4.6' into 4.7Olivier Goffart2010-03-311-19/+22
|\ \ | | | | | | | | | | | | | | | Conflicts: doc/src/modules.qdoc src/gui/graphicsview/qgraphicswidget.h
| * \ Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Thiago Macieira2010-03-311-19/+22
| |\ \ | | |/ | | | | | | | | | | | | | | | | | | Conflicts: configure doc/src/modules.qdoc src/gui/graphicsview/qgraphicsitem_p.h src/gui/graphicsview/qgraphicswidget.h
| | * Another "off by 1" problem in OpenVG - in paths this time.Rhys Weatherley2010-03-301-19/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | Summary so far: paths and images do not need the 0.5 adjustment to the transform, but glyphs do. Not sure why glyphs do, but the fonts definitely look wrong without the adjustment. Task-number: QT-3192 Reviewed-by: trustme
| * | Merge remote branch 'origin/4.6' into qt-4.7-from-4.6Thiago Macieira2010-03-292-10/+7
| |\ \ | | |/ | | | | | | | | | | | | | | | Conflicts: mkspecs/common/symbian/symbian.conf qmake/generators/symbian/symmake.cpp src/3rdparty/webkit/WebCore/WebCore.pro
* | | Merge branch '4.7' of git@scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7David Boddie2010-03-307-90/+101
|\ \ \ | |_|/ |/| | | | | | | | | | | | | | | | | | | | | | | Conflicts: doc/src/modules.qdoc mkspecs/common/symbian/symbian.conf src/gui/graphicsview/qgraphicswidget.h src/s60installs/bwins/QtGuiu.def src/s60installs/eabi/QtGuiu.def
| * | Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into ↵Qt Continuous Integration System2010-03-301-8/+3
| |\ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 4.7-integration * '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: (47 commits) QScript: More missing APIShim QScriptEngine: Fix reentrency involving creation and desctructions of QScriptEngines Work-around Symbian 10.1's broken egl.h Add some #warnings to debug Symbian EGL build failure Don't detect EGLImage presence by testing function pointers Implement proper QStaticText support in QPaintBuffer Make QStaticText layout lazy Change QStaticText::setMaximumSize() to setTextWidth() Respect QPainter::pen() in QPainter::drawStaticText() QVarLenghtArray: add some API to be consistant to QVector Don't try to resolve EGLImage function pointers if they are defined Change ORs to ANDs when checking EGLImage extension defines Protect EGLImage function definitions in #ifdef Fix a bug in greek shaping causing infinite loops Define QT_NO_EGL in configure.exe improve mingw 64 bit support Fix build on Windows Round instead of ceil font metrics when ForceIntegerMetrics is enabled cetest: remove source file duplicates from cetest.pro Remove EGLImage create/destroy resolving from VG pixmap data ...
| | * | Don't detect EGLImage presence by testing function pointersTom Cooksey2010-03-291-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | Might fix the Symbian build failures... who knows with Symbian. Reviewed-By: TrustMe
| | * | Remove EGLImage create/destroy resolving from VG pixmap dataTom Cooksey2010-03-261-6/+1
| | |/ | | | | | | | | | | | | | | | | | | eglCreateImageKHR and eglDestroyImageKHR are now defined in qegl.cpp and resolved when the display is opened with QEgl::display(). Reviewed-By: Jason Barron
| * | Merge branch '4.6' of scm.dev.nokia.troll.no:qt/qt into 4.7Alexis Menard2010-03-251-9/+4
| |\ \ | | |/ | |/| | | | | | | | | | | | | Conflicts: mkspecs/common/symbian/symbian.conf qmake/generators/symbian/symmake.cpp src/3rdparty/webkit/WebCore/WebCore.pro
| * | Merge branch '4.6-s60' into 4.7-s60axis2010-03-222-34/+33
| |\ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: configure.exe mkspecs/common/symbian/symbian.conf src/gui/graphicsview/qgraphicswidget.h src/gui/kernel/qapplication.cpp src/gui/text/qtextlayout.cpp src/openvg/qpixmapdata_vg.cpp src/s60installs/s60installs.pro tools/runonphone/main.cpp tools/runonphone/serenum_unix.cpp qtextlayout.cpp fixed up together with Eskil. Kept the configure.exe from 4.7 without recompile.
| * | | Fix compilation of OpenVG.Jason Barron2010-03-182-17/+17
| | | | | | | | | | | | | | | | | | | | | | | | As simple as QEglContext::display -> QEgl::display. Reviewed-by: Tom Cooksey