Merge remote-tracking branch 'mainline/master' into earth

This commit is contained in:
Olivier Goffart 2011-05-06 09:54:24 +02:00
commit 3a76f74e88
191 changed files with 2564 additions and 7906 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
.tag ident

1
.tag Normal file
View File

@ -0,0 +1 @@
$Id$

View File

@ -558,8 +558,11 @@ sub locateSyncProfile
# check if this is an in-source build, and if so use that as the basedir too
$basedir = locateSyncProfile($out_basedir);
$basedir = dirname($basedir) if ($basedir);
$quoted_basedir = "\Q$basedir";
if ($basedir) {
$basedir = dirname($basedir) ;
$basedir =~ s=\\=/=g;
$quoted_basedir = "\Q$basedir";
}
# --------------------------------------------------------------------
# "main" function
@ -624,6 +627,7 @@ while ( @ARGV ) {
die "Could not find a sync.profile for '$arg'\n" if (!$basedir);
$basedir = dirname($basedir);
$basedir =~ s=\\=/=g;
$quoted_basedir = "\Q$basedir";
$var = "ignore";
}
@ -743,6 +747,21 @@ mkpath "$out_basedir/include/Qt", !$quiet;
foreach my $lib (@modules_to_sync) {
#iteration info
my $dir = $modules{$lib};
my $module_version = "";
if (-e "$modulepris{$lib}") {
my $content = fileContents($modulepris{$lib});
my @version_rows = grep(/QT\..*\.VERSION/, split('\n', $content));
if(@version_rows) {
# We only pick the first one, since each module need a separate .pri file
$module_version = $version_rows[0];
chomp $module_version;
$module_version =~ s/^\s*QT\..*\.VERSION\s*=\s*([^#]+).*$/$1/;
$module_version =~ s/\s+$//;
}
}
print "WARNING: Module $lib\'s pri missing QT.<module>.VERSION variable! Private headers not versioned!\n" if (!$module_version);
my $pathtoheaders = "";
$pathtoheaders = $moduleheaders{$lib} if ($moduleheaders{$lib});
@ -762,6 +781,7 @@ foreach my $lib (@modules_to_sync) {
chomp $line;
if($line =~ /^ *QT *\+?= *([^\r\n]*)/) {
foreach(split(/ /, $1)) {
$_ =~ s/-private$//;
my $content = $mastercontent{$_};
$master_contents .= $content if ($content);
}
@ -909,7 +929,11 @@ foreach my $lib (@modules_to_sync) {
}
}
} elsif ($create_private_headers) {
@headers = ( "$out_basedir/include/$lib/private/$header" );
if ($module_version) {
@headers = ( "$out_basedir/include/$lib/$module_version/$lib/private/$header" );
} else {
@headers = ( "$out_basedir/include/$lib/private/$header" );
}
}
foreach(@headers) { #sync them
$header_copies++ if(syncHeader($_, $iheader, $copy_headers && !$shadow, $ts));

20
configure vendored
View File

@ -804,6 +804,7 @@ CFG_MAC_XARCH=auto
CFG_MAC_CARBON=no
CFG_MAC_COCOA=yes
COMMANDLINE_MAC_CARBON=no
CFG_MAC_HARFBUZZ=no
CFG_SXE=no
CFG_PREFIX_INSTALL=yes
CFG_SDK=
@ -1041,7 +1042,7 @@ while [ "$#" -gt 0 ]; do
VAL=no
;;
#Qt style yes options
-incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu)
-incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu)
VAR=`echo $1 | sed "s,^-\(.*\),\1,"`
VAL=yes
;;
@ -1499,6 +1500,13 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
harfbuzz)
if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_CARBON" != "yes" ] && [ "$VAL" = "yes" ]; then
CFG_MAC_HARFBUZZ="$VAL"
else
UNKNOWN_OPT=yes
fi
;;
framework)
if [ "$PLATFORM_MAC" = "yes" ] || [ "$PLATFORM_QPA" = "yes" ]; then
@ -4257,6 +4265,11 @@ Qt/Mac only:
-sdk <sdk> ......... Build Qt using Apple provided SDK <sdk>. This option requires gcc 4.
To use a different SDK with gcc 3.3, set the SDKROOT environment variable.
-harfbuzz .......... Use HarfBuzz to do text layout instead of Core Text when possible.
It is only available to Cocoa builds.
* -no-harfbuzz ....... Disable HarfBuzz on Mac. It can still be enabled by setting
QT_ENABLE_HARFBUZZ environment variable.
EOF
fi
@ -4921,7 +4934,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ];
-e "s,@QT_INSTALL_BINS@,\$(INSTALL_ROOT)$QMAKE_BIN_DIR,g" \
-e "s,@QT_INSTALL_DATA@,\$(INSTALL_ROOT)$QMAKE_DATA_DIR,g" \
-e "s,@QMAKE_QTOBJS@,$EXTRA_OBJS,g" -e "s,@QMAKE_QTSRCS@,$EXTRA_SRCS,g" \
-e "s,@QMAKESPEC@,$adjqmakespec,g" "$in_mkfile" >>"$mkfile"
-e "s,@QMAKESPEC@,$adjqmakespec,g" -e "s,@QT_VERSION@,$QT_VERSION,g" "$in_mkfile" >>"$mkfile"
if "$WHICH" makedepend >/dev/null 2>&1 && grep 'depend:' "$mkfile" >/dev/null 2>&1; then
(cd "$outpath/qmake" && "$MAKE" -f "$mkfile" depend) >/dev/null 2>&1
@ -7251,6 +7264,7 @@ fi
[ "$CFG_NAS" = "system" ] && QT_CONFIG="$QT_CONFIG nas"
[ "$CFG_OPENSSL" = "yes" ] && QT_CONFIG="$QT_CONFIG openssl"
[ "$CFG_OPENSSL" = "linked" ] && QT_CONFIG="$QT_CONFIG openssl-linked"
[ "$CFG_MAC_HARFBUZZ" = "yes" ] && QT_CONFIG="$QT_CONFIG harfbuzz"
if [ "$PLATFORM_X11" = "yes" ]; then
[ "$CFG_SM" = "yes" ] && QT_CONFIG="$QT_CONFIG x11sm"
@ -8500,7 +8514,7 @@ CACHEFILE="$outpath/.qmake.cache"
[ -f "$CACHEFILE.tmp" ] && rm -f "$CACHEFILE.tmp"
cat >>"$CACHEFILE.tmp" <<EOF
include(\$\$PWD/mkspecs/qmodule.pri)
CONFIG += $QMAKE_CONFIG dylib create_prl link_prl depend_includepath fix_output_dirs QTDIR_build
CONFIG += $QMAKE_CONFIG dylib create_prl link_prl depend_includepath fix_output_dirs no_private_qt_headers_warning QTDIR_build
QMAKE_ABSOLUTE_SOURCE_ROOT = \$\$QT_SOURCE_TREE
QMAKE_MOC_SRC = \$\$QT_BUILD_TREE/src/moc

Binary file not shown.

View File

@ -11,6 +11,7 @@ build_all:!build_pass {
CONFIG += release
}
TARGET = demo_shared
QT += gui-private
SOURCES += \
arthurstyle.cpp\

12
dist/changes-4.8.0 vendored
View File

@ -97,9 +97,17 @@ Qt for Windows CE
- Assistant
- Designer
* [QTBUG-18631] Enabled the use of promoted QWidgets in the buddy editor.
* [QTBUG-18120] Fixed saving of the Z-order.
* [QTBUG-13683] Fixed saving of QGridLayout and QFormLayout
by QFormBuilder.
* [QTBUG-10890] Added a filter to the rich text editor dialog.
that simplifies the HTML markup generated.
* [QTBUG-7777] Added support for QIcon::fromTheme.
* [QTBUG-7169] Fixed QtUiTools to be built with the correct
lib-infix.
* [QTBUG-3120] Added support for alignment of box layout items.
- Linguist
- Linguist GUI

View File

@ -4,4 +4,4 @@ qt:load(qt)
plugin:DEFINES += QDESIGNER_EXPORT_WIDGETS
qtAddLibrary(QtDesigner)
qtAddLibrary(QtDesigner, true)

View File

@ -1,3 +1,3 @@
QT += xml sql
qtAddModule(help)
qtAddModule(help, true)

View File

@ -0,0 +1,7 @@
!isEmpty(MODULE_PRI) {
pritarget.path = $$[QT_INSTALL_DATA]/mkspecs/modules
pritarget.files = $$MODULE_PRI
INSTALLS += pritarget
} else {
warning("Project $$basename(_PRO_FILE_) is a module, but has not defined MODULE_PRI, which is required for Qt to expose the module to other projects")
}

View File

@ -1,5 +1,7 @@
CONFIG *= moc thread
contains(QT, declarative): QT += opengl
#handle defines
win32 {
qt_static:DEFINES += QT_NODLL
@ -129,9 +131,19 @@ QMAKE_LIBDIR += $$QMAKE_LIBDIR_QT
# Topological ordering of modules based on their QT.<module>.depends variable
QT = $$resolve_depends($$QT, "QT.")
QT_DEPENDS=
unset(using_privates)
for(QTLIB, $$list($$lower($$unique(QT)))) {
# Figure out if we're wanting to use the private headers of a module
contains(QTLIB, .*-private) {
QTLIB ~= s/-private//
use_private = UsePrivate
} else {
use_private = NoPrivate
}
isEmpty(QT.$${QTLIB}.name) {
message("Warning: unknown QT module: $$QTLIB")
next()
@ -141,14 +153,21 @@ for(QTLIB, $$list($$lower($$unique(QT)))) {
warning($$TARGET cannot have a QT of $$QTLIB)
next()
}
qtAddModule($$QTLIB)
qtAddModule($$QTLIB, $$use_private)
QT_DEPENDS += $$eval(QT.$${QTLIB}.depends)
isEqual(use_private, UsePrivate):using_privates = true
}
# add include paths for all .depends, since module/application might need f.ex. template specializations etc.
QT_DEPENDS -= $$QT
for(QTLIB, $$list($$lower($$unique(QT_DEPENDS)))):INCLUDEPATH += $$INCLUDEPATH $$eval(QT.$${QTLIB}.includes)
!isEmpty(using_privates):!no_private_qt_headers_warning:if(!debug_and_release|!build_pass) {
message("This project is using private headers and will therefore be tied to this specific Qt module build version.")
message("Running this project against other versions of the Qt modules may crash at any arbitrary point.")
message("This is not a bug, but a result of using Qt internals. You have been warned!")
}
qt_compat {
!qt_compat_no_warning:QTDIR_build:warning(***USE of COMPAT inside of QTDIR!**) #just for us
INCLUDEPATH *= $$QMAKE_INCDIR_QT/Qt

View File

@ -12,7 +12,7 @@ isEmpty(QMAKE_QT_CONFIG)|!exists($$QMAKE_QT_CONFIG) {
} else {
debug(1, "Loaded .qconfig.pri from ($$QMAKE_QT_CONFIG)")
for(dir, $$list($$unique($$list($$dirname(QMAKE_QT_CONFIG) \
$$split($$list($$[QMAKE_MKSPECS]), $$DIRLIST_SEPARATOR))))) {
$$replace($$list($$split($$list($$(QMAKEPATH)), $$DIRLIST_SEPARATOR)), $, /mkspecs))))) {
debug(1, "Loading modules from $${dir}")
for(mod, $$list($$files($$dir/modules/qt_*.pri))) {
# For installed Qt these paths will be common for all modules

View File

@ -102,6 +102,16 @@ defineTest(qtAddModule) {
INCLUDEPATH -= $$MODULE_INCLUDES
INCLUDEPATH = $$MODULE_INCLUDES $$INCLUDEPATH
isEqual(2, UsePrivate) { # Tests function parameter 2 ($$2) being equal to 'UsePrivate'
# This adds both
# <module privates include path>/
# and <module privates include path>/<module name>
# since we have code using both #include <QtCore/private/foo> and #include <private/foo>
# Both need to be supported with the new private includes structure
MODULE_INCLUDES_PRIVATES = $$eval(QT.$${1}.private_includes)
INCLUDEPATH -= $$MODULE_INCLUDES_PRIVATES $$MODULE_INCLUDES_PRIVATES/$$MODULE_NAME
INCLUDEPATH = $$MODULE_INCLUDES_PRIVATES $$MODULE_INCLUDES_PRIVATES/$$MODULE_NAME $$INCLUDEPATH
}
unset(LINKAGE)
mac {
@ -140,12 +150,16 @@ defineTest(qtAddModule) {
}
isEmpty(LINKAGE):LINKAGE = -l$${MODULE_NAME}$${QT_LIBINFIX}
}
!isEmpty(QMAKE_LSB) {
QMAKE_LFLAGS *= --lsb-libpath=$$$$QMAKE_LIBDIR_QT
QMAKE_LFLAGS *= -L/opt/lsb/lib
QMAKE_LFLAGS *= --lsb-shared-libs=$${MODULE_NAME}$${QT_LIBINFIX}
# Only link to this module if a libs directory is set, else this is just a module
# to give access to sources or include files, and not for linking.
!isEmpty(MODULE_LIBS) {
!isEmpty(QMAKE_LSB) {
QMAKE_LFLAGS *= --lsb-libpath=$$$$QMAKE_LIBDIR_QT
QMAKE_LFLAGS *= -L/opt/lsb/lib
QMAKE_LFLAGS *= --lsb-shared-libs=$${MODULE_NAME}$${QT_LIBINFIX}
}
LIBS += $$LINKAGE
}
LIBS += $$LINKAGE
export(CONFIG)
export(DEFINES)
export(LIBS)

View File

@ -1,5 +1,6 @@
SOURCE_PATH = @SOURCE_PATH@
BUILD_PATH = @BUILD_PATH@
QT_VERSION = @QT_VERSION@
QTOBJS = @QMAKE_QTOBJS@
QTSRCS = @QMAKE_QTSRCS@
QMAKESPEC = @QMAKESPEC@
@ -76,6 +77,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge
CPPFLAGS = -g -I. -Igenerators -Igenerators/unix -Igenerators/win32 \
-Igenerators/mac -Igenerators/symbian -Igenerators/integrity \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \
-I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
-I$(BUILD_PATH)/src/corelib/global -I$(BUILD_PATH)/src/corelib/xml \
-I$(SOURCE_PATH)/tools/shared \
-DQT_NO_PCRE \

View File

@ -32,8 +32,8 @@ CFLAGS_BARE = -c -Fo./ \
-W3 -nologo -O2 \
$(CFLAGS_EXTRA) \
-I. -Igenerators -Igenerators\unix -Igenerators\win32 -Igenerators\mac -Igenerators\symbian -Igenerators\integrity \
-I$(BUILD_PATH)\include -I$(BUILD_PATH)\include\QtCore \
-I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore \
-I$(BUILD_PATH)\include -I$(BUILD_PATH)\include\QtCore -I$(BUILD_PATH)\include\QtCore\$(QT_VERSION) -I$(BUILD_PATH)\include\QtCore\$(QT_VERSION)\QtCore \
-I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore -I$(SOURCE_PATH)\include\QtCore\$(QT_VERSION) -I$(SOURCE_PATH)\include\QtCore\$(QT_VERSION)\QtCore \
-I$(BUILD_PATH)\src\corelib\global \
-I$(BUILD_PATH)\src\corelib\xml \
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \

View File

@ -16,8 +16,8 @@ CFLAGS = -c -o$@ -O \
-I. -Igenerators -Igenerators/unix \
-Igenerators/win32 -Igenerators/mac \
-Igenerators/symbian -Igenerators/integrity \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \
-I$(SOURCE_PATH)/include -I$(SOURCE_PATH)/include/QtCore \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
-I$(SOURCE_PATH)/include -I$(SOURCE_PATH)/include/QtCore -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION) -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
-I$(BUILD_PATH)/src/corelib/global \
-I$(BUILD_PATH)/src/corelib/xml \
-I$(SOURCE_PATH)/mkspecs/win32-g++ \

View File

@ -16,8 +16,8 @@ CFLAGS = -c -o$@ -O \
-I. -Igenerators -Igenerators/unix \
-Igenerators/win32 -Igenerators/mac \
-Igenerators/symbian -Igenerators/integrity \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \
-I$(SOURCE_PATH)/include -I$(SOURCE_PATH)/include/QtCore \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
-I$(SOURCE_PATH)/include -I$(SOURCE_PATH)/include/QtCore -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION) -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
-I$(BUILD_PATH)/src/corelib/global \
-I$(BUILD_PATH)/src/corelib/xml \
-I$(SOURCE_PATH)/mkspecs/win32-g++ \

View File

@ -2376,6 +2376,14 @@ MakefileGenerator::writeSubDirs(QTextStream &t)
qDeleteAll(targets);
}
void MakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &callPrefix,
const QString &makeArguments, const QString &callPostfix)
{
t << callPrefix
<< "$(MAKE)" << makeArguments
<< callPostfix << endl;
}
void
MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubTarget*> targets, int flags)
{
@ -2499,9 +2507,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
t << " " << valList(subtarget->depends);
if(project->isEmpty("QMAKE_NOFORCE"))
t << " FORCE";
t << out_directory_cdin
<< "$(MAKE)" << makefilein
<< out_directory_cdout << endl;
writeSubMakeCall(t, out_directory_cdin, makefilein, out_directory_cdout);
}
for(int suffix = 0; suffix < targetSuffixes.size(); ++suffix) {
@ -2521,9 +2527,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
t << " " << targets.at(target-1)->target << "-" << targetSuffixes.at(suffix) << "-ordered ";
if(project->isEmpty("QMAKE_NOFORCE"))
t << " FORCE";
t << out_directory_cdin
<< "$(MAKE)" << makefilein << " " << s
<< out_directory_cdout << endl;
writeSubMakeCall(t, out_directory_cdin, makefilein, out_directory_cdout);
}
t << subtarget->target << "-" << targetSuffixes.at(suffix) << ": " << mkfile;
if(!subtarget->depends.isEmpty())
@ -2531,9 +2535,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
"-"+targetSuffixes.at(suffix));
if(project->isEmpty("QMAKE_NOFORCE"))
t << " FORCE";
t << out_directory_cdin
<< "$(MAKE)" << makefilein << " " << s
<< out_directory_cdout << endl;
writeSubMakeCall(t, out_directory_cdin, makefilein, out_directory_cdout);
}
}
t << endl;
@ -2671,12 +2673,10 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
//write the commands
if(!out_directory.isEmpty()) {
t << out_directory_cdin
<< "$(MAKE)" << makefilein << " " << sub_targ
<< out_directory_cdout << endl;
writeSubMakeCall(t, out_directory_cdin, makefilein + " " + sub_targ,
out_directory_cdout);
} else {
t << "\n\t"
<< "$(MAKE)" << makefilein << " " << sub_targ << endl;
writeSubMakeCall(t, "\n\t", makefilein + " " + sub_targ, QString());
}
}
}

View File

@ -127,6 +127,8 @@ protected:
SubTargetsNoFlags=0x00
};
QList<MakefileGenerator::SubTarget*> findSubDirsSubTargets() const;
virtual void writeSubMakeCall(QTextStream &t, const QString &outDirectory_cdin,
const QString &makeFileIn, const QString &outDirectory_cdout);
void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags);
//extra compiler interface

View File

@ -85,6 +85,15 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
return false;
}
void NmakeMakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &callPrefix,
const QString &makeArguments, const QString &callPostfix)
{
// Pass MAKEFLAGS as environment variable to sub-make calls.
// Unlike other make tools nmake doesn't do this automatically.
t << "\n\t@set MAKEFLAGS=$(MAKEFLAGS)";
Win32MakefileGenerator::writeSubMakeCall(t, callPrefix, makeArguments, callPostfix);
}
QString NmakeMakefileGenerator::getPdbTarget()
{
return QString(project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".pdb");

View File

@ -57,6 +57,8 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator
void init();
protected:
virtual void writeSubMakeCall(QTextStream &t, const QString &callPrefix,
const QString &makeArguments, const QString &callPostfix);
virtual QString getPdbTarget();
virtual QString defaultInstall(const QString &t);
virtual QStringList &findDependencies(const QString &file);

View File

@ -27,6 +27,8 @@ INCLUDEPATH += . \
generators/symbian \
$$QT_SOURCE_TREE/include \
$$QT_SOURCE_TREE/include/QtCore \
$$QT_SOURCE_TREE/include/QtCore/$$QT_VERSION \
$$QT_SOURCE_TREE/include/QtCore/$$QT_VERSION/QtCore \
$$QT_SOURCE_TREE/qmake
VPATH += $$QT_SOURCE_TREE/tools/shared

View File

@ -122,6 +122,12 @@ win32 {
}
INSTALLS += qmake
#syncqt
syncqt.path=$$[QT_INSTALL_BINS]
syncqt.files=$$QT_BUILD_TREE/bin/syncqt
win32:syncqt.files=$$QT_BUILD_TREE/bin/syncqt.bat
INSTALLS += syncqt
#mkspecs
mkspecs.path=$$[QT_INSTALL_DATA]/mkspecs
mkspecs.files=$$QT_BUILD_TREE/mkspecs/qconfig.pri $$files($$QT_SOURCE_TREE/mkspecs/*)

View File

@ -201,16 +201,17 @@ void QUnifiedTimer::ensureTimerUpdate()
{
QUnifiedTimer *inst = QUnifiedTimer::instance(false);
if (inst && inst->isPauseTimerActive)
inst->updateAnimationsTime();
inst->updateAnimationsTime(-1);
}
void QUnifiedTimer::updateAnimationsTime()
void QUnifiedTimer::updateAnimationsTime(qint64 timeStep)
{
//setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
if(insideTick)
return;
qint64 totalElapsed = time.elapsed();
qint64 totalElapsed = timeStep >= 0 ? timeStep : time.elapsed();
// ignore consistentTiming in case the pause timer is active
int delta = (consistentTiming && !isPauseTimerActive) ?
timingInterval : totalElapsed - lastTick;
@ -260,7 +261,8 @@ void QUnifiedTimer::restartAnimationTimer()
} else if (!driver->isRunning() || isPauseTimerActive) {
driver->start();
isPauseTimerActive = false;
}
} else if (runningLeafAnimations == 0)
driver->stop();
}
void QUnifiedTimer::setTimingInterval(int interval)
@ -302,7 +304,7 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event)
if (event->timerId() == animationTimer.timerId()) {
// update current time on all top level animations
updateAnimationsTime();
updateAnimationsTime(-1);
restartAnimationTimer();
}
}
@ -389,19 +391,49 @@ int QUnifiedTimer::closestPauseAnimationTimeToFinish()
return closestTimeToFinish;
}
void QUnifiedTimer::installAnimationDriver(QAnimationDriver *d)
{
if (driver->isRunning()) {
qWarning("QUnifiedTimer: Cannot change animation driver while animations are running");
if (driver != &defaultDriver) {
qWarning("QUnifiedTimer: animation driver already installed...");
return;
}
if (driver && driver != &defaultDriver)
delete driver;
if (driver->isRunning()) {
driver->stop();
d->start();
}
driver = d;
}
void QUnifiedTimer::uninstallAnimationDriver(QAnimationDriver *d)
{
if (driver != d) {
qWarning("QUnifiedTimer: trying to uninstall a driver that is not installed...");
return;
}
driver = &defaultDriver;
if (d->isRunning()) {
d->stop();
driver->start();
}
}
/*!
Returns true if \a d is the currently installed animation driver
and is not the default animation driver (which can never be uninstalled).
*/
bool QUnifiedTimer::canUninstallAnimationDriver(QAnimationDriver *d)
{
return d == driver && driver != &defaultDriver;
}
/*!
\class QAnimationDriver
@ -424,35 +456,69 @@ QAnimationDriver::QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent)
{
}
QAnimationDriver::~QAnimationDriver()
{
QUnifiedTimer *timer = QUnifiedTimer::instance(true);
if (timer->canUninstallAnimationDriver(this))
uninstall();
}
/*!
Advances the animation based on the current time. This function should
be continuously called by the driver while the animation is running.
Advances the animation based to the specified \a timeStep. This function should
be continuously called by the driver subclasses while the animation is running.
\internal
If \a timeStep is positive, it will be used as the current time in the
calculations; otherwise, the current clock time will be used.
*/
void QAnimationDriver::advance()
void QAnimationDriver::advanceAnimation(qint64 timeStep)
{
QUnifiedTimer *instance = QUnifiedTimer::instance();
// update current time on all top level animations
instance->updateAnimationsTime();
instance->updateAnimationsTime(timeStep);
instance->restartAnimationTimer();
}
/*!
Advances the animation. This function should be continously called
by the driver while the animation is running.
*/
void QAnimationDriver::advance()
{
advanceAnimation(-1);
}
/*!
Installs this animation driver. The animation driver is thread local and
will only apply for the thread its installed in.
\internal
*/
void QAnimationDriver::install()
{
QUnifiedTimer *timer = QUnifiedTimer::instance(true);
timer->installAnimationDriver(this);
}
/*!
Uninstalls this animation driver.
*/
void QAnimationDriver::uninstall()
{
QUnifiedTimer *timer = QUnifiedTimer::instance(true);
timer->uninstallAnimationDriver(this);
}
bool QAnimationDriver::isRunning() const
{
return d_func()->running;
@ -463,7 +529,7 @@ void QAnimationDriver::start()
{
Q_D(QAnimationDriver);
if (!d->running) {
started();
emit started();
d->running = true;
}
}
@ -473,16 +539,28 @@ void QAnimationDriver::stop()
{
Q_D(QAnimationDriver);
if (d->running) {
stopped();
emit stopped();
d->running = false;
}
}
/*!
\fn qint64 QAnimationDriver::elapsed() const
Returns the number of milliseconds since the animations was started.
*/
qint64 QAnimationDriver::elapsed() const
{
return QUnifiedTimer::instance()->time.elapsed();
}
/*!
\fn QAnimationDriver::started()
This function is called by the animation framework to notify the driver
that it should start running.
This signal is emitted by the animation framework to notify the driver
that continous animation has started.
\internal
*/
@ -490,8 +568,8 @@ void QAnimationDriver::stop()
/*!
\fn QAnimationDriver::stopped()
This function is called by the animation framework to notify the driver
that it should stop running.
This signal is emitted by the animation framework to notify the driver
that continous animation has stopped.
\internal
*/

View File

@ -141,23 +141,31 @@ class Q_CORE_EXPORT QAnimationDriver : public QObject
public:
QAnimationDriver(QObject *parent = 0);
~QAnimationDriver();
virtual void advance();
void advance();
void install();
void uninstall();
bool isRunning() const;
qint64 elapsed() const;
Q_SIGNALS:
void started();
void stopped();
protected:
virtual void started() {};
virtual void stopped() {};
void advanceAnimation(qint64 timeStep = -1);
virtual void start();
virtual void stop();
QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = 0);
private:
friend class QUnifiedTimer;
void start();
void stop();
};

View File

@ -180,15 +180,21 @@ public:
static void updateAnimationTimer();
void installAnimationDriver(QAnimationDriver *driver);
void uninstallAnimationDriver(QAnimationDriver *driver);
bool canUninstallAnimationDriver(QAnimationDriver *driver);
void restartAnimationTimer();
void updateAnimationsTime();
void updateAnimationsTime(qint64 timeStep);
//useful for profiling/debugging
int runningAnimationCount() { return animations.count(); }
protected:
void timerEvent(QTimerEvent *);
private:
friend class QDefaultAnimationDriver;
friend class QAnimationDriver;
QAnimationDriver *driver;
QDefaultAnimationDriver defaultDriver;

View File

@ -1,7 +1,11 @@
MODULE = core
TARGET = QtCore
QPRO_PWD = $$PWD
QT =
CONFIG += module
MODULE = core # not corelib, as per project file
MODULE_PRI = ../modules/qt_core.pri
DEFINES += QT_BUILD_CORE_LIB QT_NO_USING_NAMESPACE
win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000
irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused

View File

@ -1843,6 +1843,10 @@ inline QT3_SUPPORT void qSuppressObsoleteWarnings(bool = true) {}
inline QT3_SUPPORT void qObsolete(const char *, const char * = 0, const char * = 0) {}
#endif
#if !defined(Q_UNIMPLEMENTED)
# define Q_UNIMPLEMENTED() qWarning("%s:%d: %s: Unimplemented code.", __FILE__, __LINE__, Q_FUNC_INFO)
#endif
#if defined(QT_NO_THREAD)
template <typename T>
@ -2755,7 +2759,8 @@ QT_LICENSED_MODULE(DBus)
#if !(defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) \
&& !(defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) \
&& !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE))
&& !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) \
&& !(defined(Q_WS_QPA))
# define QT_NO_RAWFONT
#endif

View File

@ -583,6 +583,7 @@ QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEng
}
}
#else
Q_UNUSED(entry);
Q_UNUSED(own);
#endif
return name;

View File

@ -171,17 +171,27 @@ private:
Q_GLOBAL_STATIC(QMutex, processManagerGlobalMutex)
static QProcessManager *processManager() {
static QProcessManager *processManagerInstance = 0;
static QProcessManager *processManager()
{
// The constructor of QProcessManager should be called only once
// so we cannot use Q_GLOBAL_STATIC directly for QProcessManager
QMutex *mutex = processManagerGlobalMutex();
QMutexLocker locker(mutex);
static QProcessManager processManager;
return &processManager;
if (!processManagerInstance)
QProcessPrivate::initializeProcessManager();
Q_ASSERT(processManagerInstance);
return processManagerInstance;
}
QProcessManager::QProcessManager()
{
// can only be called from main thread
Q_ASSERT(!qApp || qApp->thread() == QThread::currentThread());
#if defined (QPROCESS_DEBUG)
qDebug() << "QProcessManager::QProcessManager()";
#endif
@ -197,6 +207,8 @@ QProcessManager::QProcessManager()
action.sa_handler = qt_sa_sigchld_handler;
action.sa_flags = SA_NOCLDSTOP;
::sigaction(SIGCHLD, &action, &qt_sa_old_sigchld_handler);
processManagerInstance = this;
}
QProcessManager::~QProcessManager()
@ -221,6 +233,8 @@ QProcessManager::~QProcessManager()
if (currentAction.sa_handler == qt_sa_sigchld_handler) {
::sigaction(SIGCHLD, &qt_sa_old_sigchld_handler, 0);
}
processManagerInstance = 0;
}
void QProcessManager::run()
@ -1287,7 +1301,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
void QProcessPrivate::initializeProcessManager()
{
(void) processManager();
if (qApp && qApp->thread() != QThread::currentThread()) {
// The process manager must be initialized in the main thread
// Note: The call below will re-enter this function, but in the right thread,
// so the else statement below will be executed.
QMetaObject::invokeMethod(qApp, "_q_initializeProcessManager", Qt::BlockingQueuedConnection);
} else {
static QProcessManager processManager;
Q_UNUSED(processManager);
}
}
QT_END_NAMESPACE

View File

@ -392,6 +392,16 @@ void QCoreApplicationPrivate::createEventDispatcher()
#endif
}
void QCoreApplicationPrivate::_q_initializeProcessManager()
{
#ifndef QT_NO_PROCESS
# ifdef Q_OS_UNIX
QProcessPrivate::initializeProcessManager();
# endif
#endif
}
QThread *QCoreApplicationPrivate::theMainThread = 0;
QThread *QCoreApplicationPrivate::mainThread()
{
@ -656,12 +666,6 @@ void QCoreApplication::init()
}
#endif
#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS))
// Make sure the process manager thread object is created in the main
// thread.
QProcessPrivate::initializeProcessManager();
#endif
#ifdef QT_EVAL
extern void qt_core_eval_init(uint);
qt_core_eval_init(d->application_type);
@ -2728,3 +2732,5 @@ int QCoreApplication::loopLevel()
*/
QT_END_NAMESPACE
#include "moc_qcoreapplication.cpp"

View File

@ -205,6 +205,7 @@ protected:
QCoreApplication(QCoreApplicationPrivate &p);
private:
Q_PRIVATE_SLOT(d_func(), void _q_initializeProcessManager())
static bool sendSpontaneousEvent(QObject *receiver, QEvent *event);
bool notifyInternal(QObject *receiver, QEvent *event);

View File

@ -85,6 +85,8 @@ public:
bool sendThroughObjectEventFilters(QObject *, QEvent *);
bool notify_helper(QObject *, QEvent *);
void _q_initializeProcessManager();
virtual QString appName() const;
virtual void createEventDispatcher();
static void removePostedEvent(QEvent *);

View File

@ -1,8 +1,11 @@
TARGET = QtDBus
QPRO_PWD = $$PWD
QT = core \
QT = core-private \
xml
CONFIG += link_pkgconfig
CONFIG += link_pkgconfig module
MODULE_PRI = ../modules/qt_dbus.pri
DEFINES += QT_BUILD_DBUS_LIB \
DBUS_API_SUBJECT_TO_CHANGE
QMAKE_CXXFLAGS += $$QT_CFLAGS_DBUS

View File

@ -1,6 +1,10 @@
TARGET = QtGui
QPRO_PWD = $$PWD
QT = core
QT = core-private
CONFIG += module
MODULE_PRI = ../modules/qt_gui.pri
DEFINES += QT_BUILD_GUI_LIB QT_NO_USING_NAMESPACE
win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000
irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused

View File

@ -237,6 +237,7 @@ static void resolveAygLibs()
# define FE_FONTSMOOTHINGCLEARTYPE 0x0002
#endif
Q_GUI_EXPORT qreal qt_fontsmoothing_gamma;
Q_GUI_EXPORT bool qt_cleartype_enabled;
Q_GUI_EXPORT bool qt_win_owndc_required; // CS_OWNDC is required if we use the GL graphicssystem as default
@ -653,8 +654,18 @@ static void qt_win_read_cleartype_settings()
if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
#endif
}
int winSmooth;
if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) {
qt_fontsmoothing_gamma = winSmooth / qreal(1000.0);
} else {
qt_fontsmoothing_gamma = 1.0;
}
// Safeguard ourselves against corrupt registry values...
if (qt_fontsmoothing_gamma > 5 || qt_fontsmoothing_gamma < 1)
qt_fontsmoothing_gamma = qreal(1.4);
}
static void qt_set_windows_resources()
{

View File

@ -334,7 +334,6 @@ static int qCocoaViewCount = 0;
//
// Qt will then forward the update to the children.
if (qwidget->isWindow()) {
qwidget->update(qwidget->rect());
qwidgetprivate->syncBackingStore(qwidget->rect());
}
}

View File

@ -51,6 +51,8 @@ QT_USE_NAMESPACE
void QDesktopWidgetPrivate::updateScreenList()
{
Q_Q(QDesktopWidget);
QList<QPlatformScreen *> screenList = QApplicationPrivate::platformIntegration()->screens();
int targetLength = screenList.length();
int currentLength = screens.length();
@ -72,19 +74,15 @@ void QDesktopWidgetPrivate::updateScreenList()
}
QRegion virtualGeometry;
bool doVirtualGeometry = QApplicationPrivate::platformIntegration()->isVirtualDesktop();
// update the geometry of each screen widget
for (int i = 0; i < screens.length(); i++) {
QRect screenGeometry = screenList.at(i)->geometry();
screens.at(i)->setGeometry(screenGeometry);
if (doVirtualGeometry)
virtualGeometry += screenGeometry;
virtualGeometry += screenGeometry;
}
virtualScreen.setGeometry(virtualGeometry.boundingRect());
Q_Q(QDesktopWidget);
q->setGeometry(virtualScreen.geometry());
q->setGeometry(virtualGeometry.boundingRect());
}
QDesktopWidget::QDesktopWidget()
@ -118,8 +116,6 @@ int QDesktopWidget::numScreens() const
QWidget *QDesktopWidget::screen(int screen)
{
Q_D(QDesktopWidget);
if (QApplicationPrivate::platformIntegration()->isVirtualDesktop())
return &d->virtualScreen;
if (screen < 0 || screen >= d->screens.length())
return d->screens.at(0);
return d->screens.at(screen);

View File

@ -76,7 +76,6 @@ public:
void updateScreenList();
QList<QDesktopScreenWidget *> screens;
QDesktopScreenWidget virtualScreen;
};
#endif // QDESKTOPWIDGET_QPA_P_H

View File

@ -214,6 +214,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
bool QPlatformIntegration::hasCapability(Capability cap) const
{
Q_UNUSED(cap);
return false;
}

View File

@ -150,7 +150,7 @@ void QPlatformWindow::setParent(const QPlatformWindow *parent)
/*!
Reimplement to set the window title to \a title
*/
void QPlatformWindow::setWindowTitle(const QString &title) {}
void QPlatformWindow::setWindowTitle(const QString &) {}
/*!
Reimplement to be able to let Qt rais windows to the top of the desktop

View File

@ -42,6 +42,8 @@
#include <qsessionmanager.h>
#include <private/qobject_p.h>
#include <qapplication.h>
#ifndef QT_NO_SESSIONMANAGER
QT_BEGIN_NAMESPACE

View File

@ -7198,14 +7198,8 @@ void qt_build_pow_tables() {
#endif
#ifdef Q_WS_WIN
int winSmooth;
if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0))
smoothing = winSmooth / qreal(1000.0);
// Safeguard ourselves against corrupt registry values...
if (smoothing > 5 || smoothing < 1)
smoothing = qreal(1.4);
extern qreal qt_fontsmoothing_gamma; // qapplication_win.cpp
smoothing = qt_fontsmoothing_gamma;
#endif
#ifdef Q_WS_X11

View File

@ -100,7 +100,9 @@ QMacCGContext::QMacCGContext(QPainter *p)
int devType = p->device()->devType();
if (pe->type() == QPaintEngine::Raster
&& (devType == QInternal::Widget || devType == QInternal::Pixmap)) {
&& (devType == QInternal::Widget ||
devType == QInternal::Pixmap ||
devType == QInternal::Image)) {
extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice());

View File

@ -156,7 +156,8 @@ static bool qt_paintengine_supports_transformations(QPaintEngine::Type type)
{
return type == QPaintEngine::OpenGL2
|| type == QPaintEngine::OpenVG
|| type == QPaintEngine::OpenGL;
|| type == QPaintEngine::OpenGL
|| type == QPaintEngine::CoreGraphics;
}
#ifndef QT_NO_DEBUG
@ -5809,7 +5810,7 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs)
bool paintEngineSupportsTransformations =
d->extended != 0
? qt_paintengine_supports_transformations(d->extended->type())
: false;
: qt_paintengine_supports_transformations(d->engine->type());
for (int i=0; i<count; ++i) {
QPointF processedPosition = position + glyphPositions.at(i);
if (!paintEngineSupportsTransformations)

View File

@ -296,7 +296,7 @@ void QTextureGlyphCache::fillInPendingGlyphs()
QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const
{
#if defined(Q_WS_X11)
if (m_transform.type() > QTransform::TxTranslate) {
if (m_transform.type() > QTransform::TxTranslate && m_current_fontengine->type() == QFontEngine::Freetype) {
QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_None;
QImage::Format imageFormat = QImage::Format_Invalid;
switch (m_type) {

View File

@ -239,7 +239,7 @@ public:
bool isCopyOf(const QFont &) const;
#ifdef Q_COMPILER_RVALUE_REFS
inline QFont &operator=(QFont &&other)
{ qSwap(d, other.d); return *this; }
{ qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; }
#endif
#ifdef Q_WS_WIN

View File

@ -43,6 +43,7 @@
#include "qfont_p.h"
#include "qfontengine_p.h"
#include "qfontengine_mac_p.h"
#include "qfontengine_coretext_p.h"
#include "qfontinfo.h"
#include "qfontmetrics.h"
#include "qpaintdevice.h"
@ -119,10 +120,10 @@ quint32 QFont::macFontID() const // ### need 64-bit version
// Returns an ATSUFonFamilyRef
Qt::HANDLE QFont::handle() const
{
#if 0
#ifdef QT_MAC_USE_COCOA
QFontEngine *fe = d->engineForScript(QUnicodeTables::Common);
if (fe && fe->type() == QFontEngine::Mac)
return (Qt::HANDLE)static_cast<QFontEngineMacMulti*>(fe)->fontFamilyRef();
if (fe && fe->type() == QFontEngine::Multi)
return (Qt::HANDLE)static_cast<QCoreTextFontEngineMulti*>(fe)->macFontID();
#endif
return 0;
}

View File

@ -162,8 +162,10 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const
return engines.count() - 1;
}
bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *) const
bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *,
QScriptItem *si) const
{
QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
reinterpret_cast<const UniChar *>(str),
@ -180,6 +182,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
&kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options);
} else
#else
Q_UNUSED(flags);
#endif
typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
@ -219,6 +223,25 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl);
CFRange stringRange = CTRunGetStringRange(run);
int prepend = 0;
#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5
UniChar beginGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location);
QChar dir = QChar::direction(beginGlyph);
bool beginWithOverride = dir == QChar::DirLRO || dir == QChar::DirRLO || dir == QChar::DirLRE || dir == QChar::DirRLE;
if (beginWithOverride) {
logClusters[stringRange.location] = 0;
outGlyphs[0] = 0xFFFF;
outAdvances_x[0] = 0;
outAdvances_y[0] = 0;
outAttributes[0].clusterStart = true;
outAttributes[0].dontPrint = true;
outGlyphs++;
outAdvances_x++;
outAdvances_y++;
outAttributes++;
prepend = 1;
}
#endif
UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1);
bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF;
if (endWithPDF)
@ -233,7 +256,12 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
if (!runAttribs)
runAttribs = attributeDict;
CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName));
const uint fontIndex = (fontIndexForFont(runFont) << 24);
uint fontIndex = fontIndexForFont(runFont);
const QFontEngine *engine = engineAt(fontIndex);
fontIndex <<= 24;
si->ascent = qMax(engine->ascent(), si->ascent);
si->descent = qMax(engine->descent(), si->descent);
si->leading = qMax(engine->leading(), si->leading);
//NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
if (endWithPDF)
glyphCount--;
@ -271,9 +299,9 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
CFIndex k = 0;
CFIndex i = 0;
for (i = stringRange.location;
for (i = stringRange.location + prepend;
(i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) {
if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location + prepend) {
logClusters[i] = k + firstGlyphIndex;
outAttributes[k].clusterStart = true;
++k;
@ -308,7 +336,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
: QFixed::fromReal(lastGlyphAdvance.width);
if (endWithPDF) {
logClusters[stringRange.location + stringRange.length - 1] = glyphCount;
logClusters[stringRange.location + stringRange.length - 1] = glyphCount + prepend;
outGlyphs[glyphCount] = 0xFFFF;
outAdvances_x[glyphCount] = 0;
outAdvances_y[glyphCount] = 0;
@ -837,6 +865,15 @@ QFixed QCoreTextFontEngine::emSquareSize() const
return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
}
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
{
QFontDef newFontDef = fontDef;
newFontDef.pixelSize = pixelSize;
newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
return new QCoreTextFontEngine(cgFont, fontDef);
}
QT_END_NAMESPACE
#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)

View File

@ -91,6 +91,8 @@ public:
virtual qreal minLeftBearing() const;
virtual QFixed emSquareSize() const;
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
private:
friend class QRawFontPrivate;
@ -118,9 +120,12 @@ public:
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;
unsigned short *logClusters, const HB_CharAttributes *charAttributes,
QScriptItem *si) const;
virtual const char *name() const { return "CoreText"; }
inline CTFontRef macFontID() const { return ctfont; }
protected:
virtual void loadEngine(int at);

View File

@ -803,106 +803,6 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags,
return load_flags;
}
QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const
{
Glyph *g = set->getGlyph(glyph);
if (g && g->format == format)
return g;
bool hsubpixel = false;
int vfactor = 1;
int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor);
// apply our matrix to this, but note that the metrics will not be affected by this.
FT_Face face = lockFace();
FT_Matrix matrix = this->matrix;
FT_Matrix_Multiply(&set->transformationMatrix, &matrix);
FT_Set_Transform(face, &matrix, 0);
freetype->matrix = matrix;
bool transform = matrix.xx != 0x10000 || matrix.yy != 0x10000 || matrix.xy != 0 || matrix.yx != 0;
if (transform)
load_flags |= FT_LOAD_NO_BITMAP;
FT_Error err = FT_Load_Glyph(face, glyph, load_flags);
if (err && (load_flags & FT_LOAD_NO_BITMAP)) {
load_flags &= ~FT_LOAD_NO_BITMAP;
err = FT_Load_Glyph(face, glyph, load_flags);
}
if (err == FT_Err_Too_Few_Arguments) {
// this is an error in the bytecode interpreter, just try to run without it
load_flags |= FT_LOAD_FORCE_AUTOHINT;
err = FT_Load_Glyph(face, glyph, load_flags);
}
if (err != FT_Err_Ok)
qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
unlockFace();
if (set->outline_drawing)
return 0;
if (!g) {
g = new Glyph;
g->uploadedToServer = false;
g->data = 0;
}
FT_GlyphSlot slot = face->glyph;
if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot);
int left = slot->metrics.horiBearingX;
int right = slot->metrics.horiBearingX + slot->metrics.width;
int top = slot->metrics.horiBearingY;
int bottom = slot->metrics.horiBearingY - slot->metrics.height;
if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { // freetype doesn't apply the transformation on the metrics
int l, r, t, b;
FT_Vector vector;
vector.x = left;
vector.y = top;
FT_Vector_Transform(&vector, &matrix);
l = r = vector.x;
t = b = vector.y;
vector.x = right;
vector.y = top;
FT_Vector_Transform(&vector, &matrix);
if (l > vector.x) l = vector.x;
if (r < vector.x) r = vector.x;
if (t < vector.y) t = vector.y;
if (b > vector.y) b = vector.y;
vector.x = right;
vector.y = bottom;
FT_Vector_Transform(&vector, &matrix);
if (l > vector.x) l = vector.x;
if (r < vector.x) r = vector.x;
if (t < vector.y) t = vector.y;
if (b > vector.y) b = vector.y;
vector.x = left;
vector.y = bottom;
FT_Vector_Transform(&vector, &matrix);
if (l > vector.x) l = vector.x;
if (r < vector.x) r = vector.x;
if (t < vector.y) t = vector.y;
if (b > vector.y) b = vector.y;
left = l;
right = r;
top = t;
bottom = b;
}
left = FLOOR(left);
right = CEIL(right);
bottom = FLOOR(bottom);
top = CEIL(top);
g->linearAdvance = face->glyph->linearHoriAdvance >> 10;
g->width = TRUNC(right-left);
g->height = TRUNC(top-bottom);
g->x = TRUNC(left);
g->y = TRUNC(top);
g->advance = TRUNC(ROUND(face->glyph->advance.x));
g->format = Format_None;
return g;
}
QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
QFixed subPixelPosition,
GlyphFormat format,
@ -1697,7 +1597,7 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlag
FT_Face face = 0;
bool design = (default_hint_style == HintNone ||
default_hint_style == HintLight ||
(flags & HB_ShaperFlag_UseDesignMetrics));
(flags & HB_ShaperFlag_UseDesignMetrics)) && FT_IS_SCALABLE(freetype->face);
for (int i = 0; i < glyphs->numGlyphs; i++) {
Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]);
if (g) {
@ -2069,6 +1969,41 @@ HB_Error QFontEngineFT::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p
return result;
}
bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe)
{
if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
return false;
// Increase the reference of this QFreetypeFace since one more QFontEngineFT
// will be using it
freetype->ref.ref();
default_load_flags = fe->default_load_flags;
default_hint_style = fe->default_hint_style;
antialias = fe->antialias;
transform = fe->transform;
embolden = fe->embolden;
subpixelType = fe->subpixelType;
lcdFilterType = fe->lcdFilterType;
canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
embeddedbitmap = fe->embeddedbitmap;
return true;
}
QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const
{
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
QFontEngineFT *fe = new QFontEngineFT(fontDef);
if (!fe->initFromFontEngine(this)) {
delete fe;
return 0;
} else {
return fe;
}
}
QT_END_NAMESPACE
#endif // QT_NO_FREETYPE

View File

@ -122,7 +122,7 @@ struct QFreetypeFace
static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false);
private:
friend class QFontEngineFTRawFont;
friend class QFontEngineFT;
friend class QScopedPointerDeleter<QFreetypeFace>;
QFreetypeFace() : _lock(QMutex::Recursive) {}
~QFreetypeFace() {}
@ -311,14 +311,12 @@ private:
virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
enum HintStyle {
HintNone,
HintLight,
HintMedium,
HintFull
};
void setDefaultHintStyle(HintStyle style);
virtual void setDefaultHintStyle(HintStyle style);
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
bool initFromFontEngine(const QFontEngineFT *fontEngine);
HintStyle defaultHintStyle() const { return default_hint_style; }
protected:
@ -345,7 +343,6 @@ protected:
private:
friend class QFontEngineFTRawFont;
QFontEngineFT::Glyph *loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const;
int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
GlyphFormat defaultFormat;

View File

@ -377,7 +377,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *
}
bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *charAttributes) const
unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const
{
if (*nglyphs < len) {
*nglyphs = len;

View File

@ -131,7 +131,7 @@ public:
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;
unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const;
virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;

View File

@ -235,6 +235,8 @@ public:
virtual int glyphCount() const;
virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; }
HB_Font harfbuzzFont() const;
HB_Face harfbuzzFace() const;
@ -248,6 +250,14 @@ public:
static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
enum HintStyle {
HintNone,
HintLight,
HintMedium,
HintFull
};
virtual void setDefaultHintStyle(HintStyle) { }
QAtomicInt ref;
QFontDef fontDef;
uint cache_cost; // amount of mem used in kb by the font

View File

@ -1284,6 +1284,23 @@ QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co
return rgbMask;
}
// From qfontdatabase_win.cpp
extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
QFontEngine *QFontEngineWin::cloneWithSize(qreal pixelSize) const
{
QFontDef request = fontDef;
QString actualFontName = request.family;
if (!uniqueFamilyName.isEmpty())
request.family = uniqueFamilyName;
request.pixelSize = pixelSize;
QFontEngine *fontEngine = qt_load_font_engine_win(request);
if (fontEngine != NULL)
fontEngine->fontDef.family = actualFontName;
return fontEngine;
}
// -------------------------------------- Multi font engine
QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks)

View File

@ -106,6 +106,8 @@ public:
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
#ifndef Q_CC_MINGW
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
#endif
@ -118,6 +120,7 @@ public:
#endif
QString _name;
QString uniqueFamilyName;
HFONT hfont;
LOGFONT logfont;
uint stockFont : 1;

View File

@ -1196,6 +1196,20 @@ bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *
#endif
}
QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
{
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef);
if (!fe->initFromFontEngine(this)) {
delete fe;
return 0;
} else {
fe->xglyph_format = xglyph_format;
return fe;
}
}
#endif // QT_NO_FONTCONFIG
QT_END_NAMESPACE

View File

@ -161,6 +161,8 @@ public:
explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
~QFontEngineX11FT();
QFontEngine *cloneWithSize(qreal pixelSize) const;
#ifndef QT_NO_XRENDER
int xglyph_format;
#endif

View File

@ -630,6 +630,17 @@ QFontEngine::Type QFontEngineDirectWrite::type() const
return QFontEngine::DirectWrite;
}
QFontEngine *QFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
{
QFontEngine *fontEngine = new QFontEngineDirectWrite(m_directWriteFactory, m_directWriteFontFace,
pixelSize);
fontEngine->fontDef = fontDef;
fontEngine->fontDef.pixelSize = pixelSize;
return fontEngine;
}
QT_END_NAMESPACE
#endif // QT_NO_DIRECTWRITE

View File

@ -101,6 +101,8 @@ public:
QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin,
const QTransform &xform);
QFontEngine *cloneWithSize(qreal pixelSize) const;
bool canRender(const QChar *string, int len);
Type type() const;

View File

@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QGlyphs
\brief the QGlyphs class provides direct access to the internal glyphs in a font
\brief The QGlyphs class provides direct access to the internal glyphs in a font.
\since 4.8
\ingroup text
@ -76,8 +76,8 @@ QT_BEGIN_NAMESPACE
QTextLayout::glyphs() or QTextFragment::glyphs() can be used to convert unicode encoded text
into a list of QGlyphs objects, and QPainter::drawGlyphs() can be used to draw the glyphs.
\note Please note that QRawFont is considered local to the thread in which it is constructed,
which in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is
\note Please note that QRawFont is considered local to the thread in which it is constructed.
This in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is
moved to a different thread. If the QGlyphs contains a reference to a QRawFont from a different
thread than the current, it will not be possible to draw the glyphs using a QPainter, as the
QRawFont is considered invalid and inaccessible in this case.

View File

@ -218,6 +218,16 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode
return engine;
}
QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
Q_UNUSED(fontData);
Q_UNUSED(pixelSize);
Q_UNUSED(hintingPreference);
qWarning("This plugin does not support font engines created directly from font data");
return 0;
}
/*!
*/

View File

@ -92,6 +92,8 @@ public:
virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
virtual void releaseHandle(void *handle);
virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
virtual QString fontDir() const;
//callback

View File

@ -301,6 +301,58 @@ qreal QRawFont::descent() const
return d->fontEngine->descent().toReal();
}
/*!
Returns the xHeight of this QRawFont in pixel units.
\sa QFontMetricsF::xHeight()
*/
qreal QRawFont::xHeight() const
{
if (!isValid())
return 0.0;
return d->fontEngine->xHeight().toReal();
}
/*!
Returns the leading of this QRawFont in pixel units.
\sa QFontMetricsF::leading()
*/
qreal QRawFont::leading() const
{
if (!isValid())
return 0.0;
return d->fontEngine->leading().toReal();
}
/*!
Returns the average character width of this QRawFont in pixel units.
\sa QFontMetricsF::averageCharWidth()
*/
qreal QRawFont::averageCharWidth() const
{
if (!isValid())
return 0.0;
return d->fontEngine->averageCharWidth().toReal();
}
/*!
Returns the width of the widest character in the font.
\sa QFontMetricsF::maxWidth()
*/
qreal QRawFont::maxCharWidth() const
{
if (!isValid())
return 0.0;
return d->fontEngine->maxCharWidth();
}
/*!
Returns the pixel size set for this QRawFont. The pixel size affects how glyphs are
rasterized, the size of glyphs returned by pathForGlyph(), and is used to convert
@ -308,10 +360,10 @@ qreal QRawFont::descent() const
\sa setPixelSize()
*/
int QRawFont::pixelSize() const
qreal QRawFont::pixelSize() const
{
if (!isValid())
return -1;
return 0.0;
return d->fontEngine->fontDef.pixelSize;
}
@ -577,10 +629,21 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
/*!
Sets the pixel size with which this font should be rendered to \a pixelSize.
*/
void QRawFont::setPixelSize(int pixelSize)
void QRawFont::setPixelSize(qreal pixelSize)
{
if (d->fontEngine == 0)
return;
detach();
d->platformSetPixelSize(pixelSize);
QFontEngine *oldFontEngine = d->fontEngine;
d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
if (d->fontEngine != 0)
d->fontEngine->ref.ref();
oldFontEngine->ref.deref();
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
delete oldFontEngine;
}
/*!

View File

@ -96,13 +96,17 @@ public:
const QTransform &transform = QTransform()) const;
QPainterPath pathForGlyph(quint32 glyphIndex) const;
void setPixelSize(int pixelSize);
int pixelSize() const;
void setPixelSize(qreal pixelSize);
qreal pixelSize() const;
QFont::HintingPreference hintingPreference() const;
qreal ascent() const;
qreal descent() const;
qreal leading() const;
qreal xHeight() const;
qreal averageCharWidth() const;
qreal maxCharWidth() const;
qreal unitsPerEm() const;

View File

@ -90,32 +90,6 @@ public:
return init(faceId, true, Format_None, fontData);
}
bool initFromFontEngine(QFontEngine *oldFontEngine)
{
QFontEngineFT *fe = static_cast<QFontEngineFT *>(oldFontEngine);
// Increase the reference of this QFreetypeFace since one more QFontEngineFT
// will be using it
fe->freetype->ref.ref();
if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
return false;
default_load_flags = fe->default_load_flags;
default_hint_style = fe->default_hint_style;
antialias = fe->antialias;
transform = fe->transform;
embolden = fe->embolden;
subpixelType = fe->subpixelType;
lcdFilterType = fe->lcdFilterType;
canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
embeddedbitmap = fe->embeddedbitmap;
#if defined(Q_WS_X11)
xglyph_format = static_cast<QFontEngineX11FT *>(fe)->xglyph_format;
#endif
return true;
}
};
@ -159,31 +133,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixel
fontEngine->ref.ref();
}
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
{
if (fontEngine == NULL)
return;
QFontEngine *oldFontEngine = fontEngine;
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef);
if (!fe->initFromFontEngine(oldFontEngine)) {
delete fe;
return;
}
fontEngine = fe;
fontEngine->fontDef = oldFontEngine->fontDef;
fontEngine->fontDef.pixelSize = pixelSize;
fontEngine->ref.ref();
Q_ASSERT(fontEngine != oldFontEngine);
oldFontEngine->ref.deref();
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
delete oldFontEngine;
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -78,28 +78,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
}
}
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
{
if (fontEngine == NULL)
return;
QFontEngine *oldFontEngine = fontEngine;
QFontDef fontDef = oldFontEngine->fontDef;
fontDef.pixelSize = pixelSize;
fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
QCoreTextFontEngine *ctFontEngine = static_cast<QCoreTextFontEngine *>(oldFontEngine);
Q_ASSERT(ctFontEngine->cgFont);
fontEngine = new QCoreTextFontEngine(ctFontEngine->cgFont, fontDef);
fontEngine->ref.ref();
Q_ASSERT(fontEngine != oldFontEngine);
oldFontEngine->ref.deref();
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
delete oldFontEngine;
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -62,7 +62,7 @@
QT_BEGIN_NAMESPACE
namespace { class CustomFontFileLoader; }
class Q_AUTOTEST_EXPORT QRawFontPrivate
class Q_GUI_EXPORT QRawFontPrivate
{
public:
QRawFontPrivate()
@ -83,7 +83,6 @@ public:
, fontHandle(NULL)
, ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx)
, ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx)
, uniqueFamilyName(other.uniqueFamilyName)
#endif
{
fontEngine = other.fontEngine;
@ -102,7 +101,6 @@ public:
void platformLoadFromData(const QByteArray &fontData,
int pixelSize,
QFont::HintingPreference hintingPreference);
void platformSetPixelSize(int pixelSize);
static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); }
@ -120,8 +118,6 @@ public:
PtrAddFontMemResourceEx ptrAddFontMemResourceEx;
PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx;
QString uniqueFamilyName;
#endif // Q_WS_WIN
};

View File

@ -0,0 +1,69 @@
/****************************************************************************
**
** Copyright (C) 2011 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 <QtCore/qglobal.h>
#if !defined(QT_NO_RAWFONT)
#include "qrawfont_p.h"
#include <QtGui/qplatformfontdatabase_qpa.h>
#include <private/qapplication_p.h>
QT_BEGIN_NAMESPACE
void QRawFontPrivate::platformCleanUp()
{
}
void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize,
QFont::HintingPreference hintingPreference)
{
Q_ASSERT(fontEngine == 0);
QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference);
if (fontEngine != 0)
fontEngine->ref.ref();
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -559,7 +559,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
GUID guid;
CoCreateGuid(&guid);
uniqueFamilyName = QString::fromLatin1("f")
QString uniqueFamilyName = QString::fromLatin1("f")
+ QString::number(guid.Data1, 36) + QLatin1Char('-')
+ QString::number(guid.Data2, 36) + QLatin1Char('-')
+ QString::number(guid.Data3, 36) + QLatin1Char('-')
@ -613,6 +613,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0);
// Override the generated font name
static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName;
fontEngine->fontDef.family = actualFontName;
fontEngine->ref.ref();
}
@ -701,50 +702,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
}
}
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
{
if (fontEngine == NULL)
return;
QFontEngine *oldFontEngine = fontEngine;
#if !defined(QT_NO_DIRECTWRITE)
if (fontEngine->type() == QFontEngine::Win)
#endif
{
QFontDef request = fontEngine->fontDef;
QString actualFontName = request.family;
if (!uniqueFamilyName.isEmpty())
request.family = uniqueFamilyName;
request.pixelSize = pixelSize;
fontEngine = qt_load_font_engine_win(request);
if (fontEngine != NULL) {
fontEngine->fontDef.family = actualFontName;
fontEngine->ref.ref();
}
}
#if !defined(QT_NO_DIRECTWRITE)
else {
QFontEngineDirectWrite *dWriteFE = static_cast<QFontEngineDirectWrite *>(fontEngine);
fontEngine = new QFontEngineDirectWrite(dWriteFE->m_directWriteFactory,
dWriteFE->m_directWriteFontFace,
pixelSize);
fontEngine->fontDef = dWriteFE->fontDef;
fontEngine->fontDef.pixelSize = pixelSize;
fontEngine->ref.ref();
}
#endif
Q_ASSERT(fontEngine != oldFontEngine);
oldFontEngine->ref.deref();
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
delete oldFontEngine;
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -714,17 +714,13 @@ QStaticTextItem::~QStaticTextItem()
{
if (m_userData != 0 && !m_userData->ref.deref())
delete m_userData;
if (!m_fontEngine->ref.deref())
delete m_fontEngine;
m_fontEngine->ref.deref();
}
void QStaticTextItem::setFontEngine(QFontEngine *fe)
{
if (m_fontEngine != 0) {
if (!m_fontEngine->ref.deref())
delete m_fontEngine;
}
if (m_fontEngine != 0)
m_fontEngine->ref.deref();
m_fontEngine = fe;
if (m_fontEngine != 0)
m_fontEngine->ref.ref();

View File

@ -362,20 +362,23 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor
currentCharFormat = -1;
bool adjustX = true;
QTextBlock blockIt = block();
bool visualMovement = priv->defaultCursorMoveStyle == QTextCursor::Visual;
if (!blockIt.isValid())
return false;
if (op >= QTextCursor::Left && op <= QTextCursor::WordRight
&& blockIt.textDirection() == Qt::RightToLeft) {
if (op == QTextCursor::Left)
op = QTextCursor::NextCharacter;
else if (op == QTextCursor::Right)
op = QTextCursor::PreviousCharacter;
else if (op == QTextCursor::WordLeft)
if (blockIt.textDirection() == Qt::RightToLeft) {
if (op == QTextCursor::WordLeft)
op = QTextCursor::NextWord;
else if (op == QTextCursor::WordRight)
op = QTextCursor::PreviousWord;
if (!visualMovement) {
if (op == QTextCursor::Left)
op = QTextCursor::NextCharacter;
else if (op == QTextCursor::Right)
op = QTextCursor::PreviousCharacter;
}
}
const QTextLayout *layout = blockLayout(blockIt);
@ -418,9 +421,12 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor
break;
}
case QTextCursor::PreviousCharacter:
case QTextCursor::Left:
newPosition = priv->previousCursorPosition(position, QTextLayout::SkipCharacters);
break;
case QTextCursor::Left:
newPosition = visualMovement ? priv->leftCursorPosition(position)
: priv->previousCursorPosition(position, QTextLayout::SkipCharacters);
break;
case QTextCursor::StartOfWord: {
if (relativePos == 0)
break;
@ -529,9 +535,12 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor
break;
}
case QTextCursor::NextCharacter:
case QTextCursor::Right:
newPosition = priv->nextCursorPosition(position, QTextLayout::SkipCharacters);
break;
case QTextCursor::Right:
newPosition = visualMovement ? priv->rightCursorPosition(position)
: priv->nextCursorPosition(position, QTextLayout::SkipCharacters);
break;
case QTextCursor::NextWord:
case QTextCursor::WordRight:
newPosition = priv->nextCursorPosition(position, QTextLayout::SkipWords);
@ -2558,4 +2567,19 @@ QTextDocument *QTextCursor::document() const
return 0; // document went away
}
/*!
\enum QTextCursor::MoveStyle
This enum describes the movement style available to QTextCursor. The options
are:
\value Logical Within a left-to-right text block, increase cursor position
when pressing left arrow key, decrease cursor position when pressing the
right arrow key. If the text block is right-to-left, the opposite behavior
applies.
\value Visual Pressing the left arrow key will always cause the cursor to move
left, regardless of the text's writing direction. The same behavior applies to
right arrow key.
*/
QT_END_NAMESPACE

View File

@ -86,6 +86,10 @@ public:
MoveAnchor,
KeepAnchor
};
enum MoveStyle {
Logical,
Visual
};
void setPosition(int pos, MoveMode mode = MoveAnchor);
int position() const;

View File

@ -585,6 +585,29 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option)
d->lout->documentChanged(0, 0, d->length());
}
/*!
\since 4.8
The default cursor movement style is used by all QTextCursor objects
created from the document. The default is QTextCursor::Logical.
*/
QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle() const
{
Q_D(const QTextDocument);
return d->defaultCursorMoveStyle;
}
/*!
\since 4.8
Set the default cursor movement style.
*/
void QTextDocument::setDefaultCursorMoveStyle(QTextCursor::MoveStyle style)
{
Q_D(QTextDocument);
d->defaultCursorMoveStyle = style;
}
/*!
\fn void QTextDocument::markContentsDirty(int position, int length)
@ -2076,6 +2099,10 @@ QString QTextHtmlExporter::toHtml(const QByteArray &encoding, ExportMode mode)
html += QLatin1String(" font-size:");
html += QString::number(defaultCharFormat.fontPointSize());
html += QLatin1String("pt;");
} else if (defaultCharFormat.hasProperty(QTextFormat::FontPixelSize)) {
html += QLatin1String(" font-size:");
html += QString::number(defaultCharFormat.intProperty(QTextFormat::FontPixelSize));
html += QLatin1String("px;");
}
html += QLatin1String(" font-weight:");
@ -2156,6 +2183,10 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format)
html += QLatin1Char(';');
attributesEmitted = true;
}
} else if (format.hasProperty(QTextFormat::FontPixelSize)) {
html += QLatin1String(" font-size:");
html += QString::number(format.intProperty(QTextFormat::FontPixelSize));
html += QLatin1String("px;");
}
if (format.hasProperty(QTextFormat::FontWeight)

View File

@ -46,6 +46,7 @@
#include <QtCore/qsize.h>
#include <QtCore/qrect.h>
#include <QtGui/qfont.h>
#include <QtGui/qtextcursor.h>
QT_BEGIN_HEADER
@ -60,7 +61,6 @@ class QPainter;
class QPrinter;
class QAbstractTextDocumentLayout;
class QPoint;
class QTextCursor;
class QTextObject;
class QTextFormat;
class QTextFrame;
@ -269,6 +269,9 @@ public:
QTextOption defaultTextOption() const;
void setDefaultTextOption(const QTextOption &option);
QTextCursor::MoveStyle defaultCursorMoveStyle() const;
void setDefaultCursorMoveStyle(QTextCursor::MoveStyle style);
Q_SIGNALS:
void contentsChange(int from, int charsRemoves, int charsAdded);
void contentsChanged();

View File

@ -209,6 +209,7 @@ QTextDocumentPrivate::QTextDocumentPrivate()
defaultTextOption.setTabStop(80); // same as in qtextengine.cpp
defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
defaultCursorMoveStyle = QTextCursor::Logical;
indentWidth = 40;
documentMargin = 4;
@ -1382,6 +1383,20 @@ int QTextDocumentPrivate::previousCursorPosition(int position, QTextLayout::Curs
return it.layout()->previousCursorPosition(position-start, mode) + start;
}
int QTextDocumentPrivate::leftCursorPosition(int position) const
{
QTextBlock it = blocksFind(position);
int start = it.position();
return it.layout()->leftCursorPosition(position-start) + start;
}
int QTextDocumentPrivate::rightCursorPosition(int position) const
{
QTextBlock it = blocksFind(position);
int start = it.position();
return it.layout()->rightCursorPosition(position-start) + start;
}
void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format)
{
beginEditBlock();

View File

@ -64,6 +64,7 @@
#include "private/qtextformat_p.h"
#include "QtGui/qtextdocument.h"
#include "QtGui/qtextobject.h"
#include "QtGui/qtextcursor.h"
#include "QtCore/qmap.h"
#include "QtCore/qvariant.h"
#include "QtCore/qurl.h"
@ -244,6 +245,8 @@ public:
int nextCursorPosition(int position, QTextLayout::CursorMode mode) const;
int previousCursorPosition(int position, QTextLayout::CursorMode mode) const;
int leftCursorPosition(int position) const;
int rightCursorPosition(int position) const;
void changeObjectFormat(QTextObject *group, int format);
@ -339,6 +342,7 @@ private:
public:
QTextOption defaultTextOption;
QTextCursor::MoveStyle defaultCursorMoveStyle;
#ifndef QT_NO_CSSPARSER
QCss::StyleSheet parsedDefaultStyleSheet;
#endif

View File

@ -2996,10 +2996,19 @@ void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDo
QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0));
item.setWidth(inlineSize.width());
if (f.verticalAlignment() == QTextCharFormat::AlignMiddle) {
QFontMetrics m(f.font());
switch (f.verticalAlignment())
{
case QTextCharFormat::AlignMiddle:
item.setDescent(inlineSize.height() / 2);
item.setAscent(inlineSize.height() / 2 - 1);
} else {
break;
case QTextCharFormat::AlignBaseline:
item.setDescent(m.descent());
item.setAscent(inlineSize.height() - m.descent() - 1);
break;
default:
item.setDescent(0);
item.setAscent(inlineSize.height() - 1);
}

View File

@ -856,6 +856,21 @@ void QTextEngine::shapeLine(const QScriptLine &line)
}
}
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
static bool enableHarfBuzz()
{
static enum { Yes, No, Unknown } status = Unknown;
if (status == Unknown) {
QByteArray v = qgetenv("QT_ENABLE_HARFBUZZ");
bool value = !v.isEmpty() && v != "0" && v != "false";
if (value) status = Yes;
else status = No;
}
return status == Yes;
}
#endif
void QTextEngine::shapeText(int item) const
{
Q_ASSERT(item < layoutData->items.size());
@ -865,7 +880,24 @@ void QTextEngine::shapeText(int item) const
return;
#if defined(Q_WS_MAC)
shapeTextMac(item);
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
if (enableHarfBuzz()) {
#endif
QFontEngine *actualFontEngine = fontEngine(si, &si.ascent, &si.descent, &si.leading);
if (actualFontEngine->type() == QFontEngine::Multi)
actualFontEngine = static_cast<QFontEngineMulti *>(actualFontEngine)->engine(0);
HB_Face face = actualFontEngine->harfbuzzFace();
HB_Script script = (HB_Script) si.analysis.script;
if (face->supported_scripts[script])
shapeTextWithHarfbuzz(item);
else
shapeTextMac(item);
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
} else {
shapeTextMac(item);
}
#endif
#elif defined(Q_WS_WINCE)
shapeTextWithCE(item);
#else
@ -1242,6 +1274,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
}
si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
si.descent = qMax(actualFontEngine->descent(), si.descent);
si.leading = qMax(actualFontEngine->leading(), si.leading);
shaper_item.font = actualFontEngine->harfbuzzFont();
shaper_item.face = actualFontEngine->harfbuzzFace();
@ -1304,6 +1340,7 @@ static void init(QTextEngine *e)
e->ignoreBidi = false;
e->cacheGlyphs = false;
e->forceJustification = false;
e->visualMovement = false;
e->layoutData = 0;
@ -1565,6 +1602,8 @@ bool QTextEngine::isRightToLeft() const
default:
break;
}
if (!layoutData)
itemize();
// this places the cursor in the right position depending on the keyboard layout
if (layoutData->string.isEmpty())
return QApplication::keyboardInputDirection() == Qt::RightToLeft;
@ -2737,6 +2776,182 @@ QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line)
return width(line.from + pos, line.length - pos);
}
QFixed QTextEngine::alignLine(const QScriptLine &line)
{
QFixed x = 0;
justify(line);
// if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned.
if (!line.justified && line.width != QFIXED_MAX) {
int align = option.alignment();
if (align & Qt::AlignLeft)
x -= leadingSpaceWidth(line);
if (align & Qt::AlignJustify && isRightToLeft())
align = Qt::AlignRight;
if (align & Qt::AlignRight)
x = line.width - (line.textAdvance + leadingSpaceWidth(line));
else if (align & Qt::AlignHCenter)
x = (line.width - (line.textAdvance + leadingSpaceWidth(line)))/2;
}
return x;
}
QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos)
{
unsigned short *logClusters = this->logClusters(si);
const QGlyphLayout &glyphs = shapedGlyphs(si);
int offsetInCluster = 0;
for (int i = pos - 1; i >= 0; i--) {
if (logClusters[i] == glyph_pos)
offsetInCluster++;
else
break;
}
// in the case that the offset is inside a (multi-character) glyph,
// interpolate the position.
if (offsetInCluster > 0) {
int clusterLength = 0;
for (int i = pos - offsetInCluster; i < max; i++) {
if (logClusters[i] == glyph_pos)
clusterLength++;
else
break;
}
if (clusterLength)
return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
}
return 0;
}
int QTextEngine::previousLogicalPosition(int oldPos) const
{
const HB_CharAttributes *attrs = attributes();
if (!attrs || oldPos < 0)
return oldPos;
if (oldPos <= 0)
return 0;
oldPos--;
while (oldPos && !attrs[oldPos].charStop)
oldPos--;
return oldPos;
}
int QTextEngine::nextLogicalPosition(int oldPos) const
{
const HB_CharAttributes *attrs = attributes();
int len = block.isValid() ? block.length() - 1
: layoutData->string.length();
Q_ASSERT(len <= layoutData->string.length());
if (!attrs || oldPos < 0 || oldPos >= len)
return oldPos;
oldPos++;
while (oldPos < len && !attrs[oldPos].charStop)
oldPos++;
return oldPos;
}
int QTextEngine::lineNumberForTextPosition(int pos)
{
if (!layoutData)
itemize();
if (pos == layoutData->string.length() && lines.size())
return lines.size() - 1;
for (int i = 0; i < lines.size(); ++i) {
const QScriptLine& line = lines[i];
if (line.from + line.length > pos)
return i;
}
return -1;
}
void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoints)
{
QTextLineItemIterator iterator(this, lineNum);
bool rtl = isRightToLeft();
bool lastLine = lineNum >= lines.size() - 1;
while (!iterator.atEnd()) {
iterator.next();
const QScriptItem *si = &layoutData->items[iterator.item];
if (si->analysis.bidiLevel % 2) {
int i = iterator.itemEnd - 1, min = iterator.itemStart;
if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
i++;
for (; i >= min; i--)
insertionPoints.push_back(i);
} else {
int i = iterator.itemStart, max = iterator.itemEnd;
if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
max++;
for (; i < max; i++)
insertionPoints.push_back(i);
}
}
}
int QTextEngine::endOfLine(int lineNum)
{
QVector<int> insertionPoints;
insertionPointsForLine(lineNum, insertionPoints);
if (insertionPoints.size() > 0)
return insertionPoints.last();
return 0;
}
int QTextEngine::beginningOfLine(int lineNum)
{
QVector<int> insertionPoints;
insertionPointsForLine(lineNum, insertionPoints);
if (insertionPoints.size() > 0)
return insertionPoints.first();
return 0;
}
int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op)
{
if (!layoutData)
itemize();
bool moveRight = (op == QTextCursor::Right);
bool alignRight = isRightToLeft();
if (!layoutData->hasBidi)
return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos);
int lineNum = lineNumberForTextPosition(pos);
Q_ASSERT(lineNum >= 0);
QVector<int> insertionPoints;
insertionPointsForLine(lineNum, insertionPoints);
int i, max = insertionPoints.size();
for (i = 0; i < max; i++)
if (pos == insertionPoints[i]) {
if (moveRight) {
if (i + 1 < max)
return insertionPoints[i + 1];
} else {
if (i > 0)
return insertionPoints[i - 1];
}
if (moveRight ^ alignRight) {
if (lineNum + 1 < lines.size())
return alignRight ? endOfLine(lineNum + 1) : beginningOfLine(lineNum + 1);
}
else {
if (lineNum > 0)
return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1);
}
}
return pos;
}
QStackTextEngine::QStackTextEngine(const QString &string, const QFont &f)
: QTextEngine(string, f),
_layoutData(string, _memory, MemSize)
@ -2841,5 +3056,127 @@ glyph_metrics_t glyph_metrics_t::transformed(const QTransform &matrix) const
return m;
}
QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, const QPointF &pos,
const QTextLayout::FormatRange *_selection)
: eng(_eng),
line(eng->lines[_lineNum]),
si(0),
lineNum(_lineNum),
lineEnd(line.from + line.length),
firstItem(eng->findItem(line.from)),
lastItem(eng->findItem(lineEnd - 1)),
nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
logicalItem(-1),
item(-1),
visualOrder(nItems),
levels(nItems),
selection(_selection)
{
pos_x = x = QFixed::fromReal(pos.x());
x += line.x;
x += eng->alignLine(line);
for (int i = 0; i < nItems; ++i)
levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
eng->shapeLine(line);
}
QScriptItem &QTextLineItemIterator::next()
{
x += itemWidth;
++logicalItem;
item = visualOrder[logicalItem] + firstItem;
itemLength = eng->length(item);
si = &eng->layoutData->items[item];
if (!si->num_glyphs)
eng->shape(item);
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
itemWidth = si->width;
return *si;
}
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
itemStart = qMax(line.from, si->position);
glyphsStart = logClusters[itemStart - si->position];
if (lineEnd < si->position + itemLength) {
itemEnd = lineEnd;
glyphsEnd = logClusters[itemEnd-si->position];
} else {
itemEnd = si->position + itemLength;
glyphsEnd = si->num_glyphs;
}
// show soft-hyphen at line-break
if (si->position + itemLength >= lineEnd
&& eng->layoutData->string.at(lineEnd - 1) == 0x00ad)
glyphs.attributes[glyphsEnd - 1].dontPrint = false;
itemWidth = 0;
for (int g = glyphsStart; g < glyphsEnd; ++g)
itemWidth += glyphs.effectiveAdvance(g);
return *si;
}
bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const
{
*selectionX = *selectionWidth = 0;
if (!selection)
return false;
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
if (si->position >= selection->start + selection->length
|| si->position + itemLength <= selection->start)
return false;
*selectionX = x;
*selectionWidth = itemWidth;
} else {
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
int from = qMax(itemStart, selection->start) - si->position;
int to = qMin(itemEnd, selection->start + selection->length) - si->position;
if (from >= to)
return false;
int start_glyph = logClusters[from];
int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to];
QFixed soff;
QFixed swidth;
if (si->analysis.bidiLevel %2) {
for (int g = glyphsEnd - 1; g >= end_glyph; --g)
soff += glyphs.effectiveAdvance(g);
for (int g = end_glyph - 1; g >= start_glyph; --g)
swidth += glyphs.effectiveAdvance(g);
} else {
for (int g = glyphsStart; g < start_glyph; ++g)
soff += glyphs.effectiveAdvance(g);
for (int g = start_glyph; g < end_glyph; ++g)
swidth += glyphs.effectiveAdvance(g);
}
// If the starting character is in the middle of a ligature,
// selection should only contain the right part of that ligature
// glyph, so we need to get the width of the left part here and
// add it to *selectionX
QFixed leftOffsetInLigature = eng->offsetInLigature(si, from, to, start_glyph);
*selectionX = x + soff + leftOffsetInLigature;
*selectionWidth = swidth - leftOffsetInLigature;
// If the ending character is also part of a ligature, swidth does
// not contain that part yet, we also need to find out the width of
// that left part
*selectionWidth += eng->offsetInLigature(si, to, eng->length(item), end_glyph);
}
return true;
}
QT_END_NAMESPACE

View File

@ -605,11 +605,11 @@ void QTextEngine::shapeTextMac(int item) const
unsigned short *log_clusters = logClusters(&si);
bool stringToCMapFailed = false;
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) {
ensureSpace(num_glyphs);
g = availableGlyphs(&si);
stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
attributes());
attributes(), &si);
}
if (!stringToCMapFailed) {

View File

@ -64,6 +64,7 @@
#include "QtGui/qpaintengine.h"
#include "QtGui/qtextobject.h"
#include "QtGui/qtextoption.h"
#include "QtGui/qtextcursor.h"
#include "QtCore/qset.h"
#include "QtCore/qdebug.h"
#ifndef QT_BUILD_COMPAT_LIB
@ -471,6 +472,7 @@ public:
void shape(int item) const;
void justify(const QScriptLine &si);
QFixed alignLine(const QScriptLine &line);
QFixed width(int charFrom, int numChars) const;
glyph_metrics_t boundingBox(int from, int len) const;
@ -586,12 +588,18 @@ public:
uint cacheGlyphs : 1;
uint stackEngine : 1;
uint forceJustification : 1;
uint visualMovement : 1;
int *underlinePositions;
mutable LayoutData *layoutData;
inline bool hasFormats() const { return (block.docHandle() || specialData); }
inline bool visualCursorMovement() const
{
return (visualMovement ||
(block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == QTextCursor::Visual : false));
}
struct SpecialData {
int preeditPosition;
@ -611,6 +619,13 @@ public:
void shapeLine(const QScriptLine &line);
QFixed leadingSpaceWidth(const QScriptLine &line);
QFixed offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos);
int previousLogicalPosition(int oldPos) const;
int nextLogicalPosition(int oldPos) const;
int lineNumberForTextPosition(int pos);
int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op);
void insertionPointsForLine(int lineNum, QVector<int> &insertionPoints);
private:
void setBoundary(int strPos) const;
void addRequiredBoundaries() const;
@ -625,6 +640,8 @@ private:
void splitItem(int item, int pos) const;
void resolveAdditionalFormats() const;
int endOfLine(int lineNum);
int beginningOfLine(int lineNum);
};
class QStackTextEngine : public QTextEngine {
@ -635,6 +652,49 @@ public:
void *_memory[MemSize];
};
struct QTextLineItemIterator
{
QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(),
const QTextLayout::FormatRange *_selection = 0);
inline bool atEnd() const { return logicalItem >= nItems - 1; }
inline bool atBeginning() const { return logicalItem <= 0; }
QScriptItem &next();
bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const;
inline bool isOutsideSelection() const {
QFixed tmp1, tmp2;
return !getSelectionBounds(&tmp1, &tmp2);
}
QTextEngine *eng;
QFixed x;
QFixed pos_x;
const QScriptLine &line;
QScriptItem *si;
int lineNum;
int lineEnd;
int firstItem;
int lastItem;
int nItems;
int logicalItem;
int item;
int itemLength;
int glyphsStart;
int glyphsEnd;
int itemStart;
int itemEnd;
QFixed itemWidth;
QVarLengthArray<int> visualOrder;
QVarLengthArray<uchar> levels;
const QTextLayout::FormatRange *selection;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QTextEngine::ShaperFlags)

View File

@ -378,7 +378,8 @@ public:
AlignSubScript,
AlignMiddle,
AlignTop,
AlignBottom
AlignBottom,
AlignBaseline
};
enum UnderlineStyle { // keep in sync with Qt::PenStyle!
NoUnderline,

View File

@ -72,23 +72,6 @@ QT_BEGIN_NAMESPACE
#define SuppressText 0x5012
#define SuppressBackground 0x513
static QFixed alignLine(QTextEngine *eng, const QScriptLine &line)
{
QFixed x = 0;
eng->justify(line);
// if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned.
if (!line.justified && line.width != QFIXED_MAX) {
int align = eng->option.alignment();
if (align & Qt::AlignJustify && eng->isRightToLeft())
align = Qt::AlignRight;
if (align & Qt::AlignRight)
x = line.width - (line.textAdvance + eng->leadingSpaceWidth(line));
else if (align & Qt::AlignHCenter)
x = (line.width - line.textAdvance)/2;
}
return x;
}
/*!
\class QTextLayout::FormatRange
\reentrant
@ -595,6 +578,30 @@ bool QTextLayout::cacheEnabled() const
return d->cacheGlyphs;
}
/*!
Set the visual cursor movement style. If the QTextLayout is backed by
a document, you can ignore this and use the option in QTextDocument,
this option is for widgets like QLineEdit or custom widgets without
a QTextDocument. Default value is QTextCursor::Logical.
\sa setCursorMoveStyle()
*/
void QTextLayout::setCursorMoveStyle(QTextCursor::MoveStyle style)
{
d->visualMovement = style == QTextCursor::Visual ? true : false;
}
/*!
The cursor movement style of this QTextLayout. The default is
QTextCursor::Logical.
\sa setCursorMoveStyle()
*/
QTextCursor::MoveStyle QTextLayout::cursorMoveStyle() const
{
return d->visualMovement ? QTextCursor::Visual : QTextCursor::Logical;
}
/*!
Begins the layout process.
@ -718,6 +725,34 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
}
/*!
Returns the cursor position to the right of \a oldPos, next to it.
It's dependent on the visual position of characters, after bi-directional
reordering.
\sa leftCursorPosition(), nextCursorPosition()
*/
int QTextLayout::rightCursorPosition(int oldPos) const
{
int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Right);
// qDebug("%d -> %d", oldPos, newPos);
return newPos;
}
/*!
Returns the cursor position to the left of \a oldPos, next to it.
It's dependent on the visual position of characters, after bi-directional
reordering.
\sa rightCursorPosition(), previousCursorPosition()
*/
int QTextLayout::leftCursorPosition(int oldPos) const
{
int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Left);
// qDebug("%d -> %d", oldPos, newPos);
return newPos;
}
/*!/
Returns true if position \a pos is a valid cursor position.
In a Unicode context some positions in the text are not valid
@ -815,16 +850,8 @@ QTextLine QTextLayout::lineAt(int i) const
*/
QTextLine QTextLayout::lineForTextPosition(int pos) const
{
for (int i = 0; i < d->lines.size(); ++i) {
const QScriptLine& line = d->lines[i];
if (line.from + (int)line.length > pos)
return QTextLine(i, d);
}
if (!d->layoutData)
d->itemize();
if (pos == d->layoutData->string.length() && d->lines.size())
return QTextLine(d->lines.size()-1, d);
return QTextLine();
int lineNum = d->lineNumberForTextPosition(pos);
return lineNum >= 0 ? lineAt(lineNum) : QTextLine();
}
/*!
@ -919,201 +946,6 @@ void QTextLayout::setFlags(int flags)
}
}
struct QTextLineItemIterator
{
QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(),
const QTextLayout::FormatRange *_selection = 0);
inline bool atEnd() const { return logicalItem >= nItems - 1; }
QScriptItem &next();
bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const;
inline bool isOutsideSelection() const {
QFixed tmp1, tmp2;
return !getSelectionBounds(&tmp1, &tmp2);
}
QTextEngine *eng;
QFixed x;
QFixed pos_x;
const QScriptLine &line;
QScriptItem *si;
int lineEnd;
int firstItem;
int lastItem;
int nItems;
int logicalItem;
int item;
int itemLength;
int glyphsStart;
int glyphsEnd;
int itemStart;
int itemEnd;
QFixed itemWidth;
QVarLengthArray<int> visualOrder;
QVarLengthArray<uchar> levels;
const QTextLayout::FormatRange *selection;
};
QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int lineNum, const QPointF &pos,
const QTextLayout::FormatRange *_selection)
: eng(_eng),
line(eng->lines[lineNum]),
si(0),
lineEnd(line.from + line.length),
firstItem(eng->findItem(line.from)),
lastItem(eng->findItem(lineEnd - 1)),
nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
logicalItem(-1),
item(-1),
visualOrder(nItems),
levels(nItems),
selection(_selection)
{
pos_x = x = QFixed::fromReal(pos.x());
x += line.x;
x += alignLine(eng, line);
for (int i = 0; i < nItems; ++i)
levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
eng->shapeLine(line);
}
QScriptItem &QTextLineItemIterator::next()
{
x += itemWidth;
++logicalItem;
item = visualOrder[logicalItem] + firstItem;
itemLength = eng->length(item);
si = &eng->layoutData->items[item];
if (!si->num_glyphs)
eng->shape(item);
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
itemWidth = si->width;
return *si;
}
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
itemStart = qMax(line.from, si->position);
glyphsStart = logClusters[itemStart - si->position];
if (lineEnd < si->position + itemLength) {
itemEnd = lineEnd;
glyphsEnd = logClusters[itemEnd-si->position];
} else {
itemEnd = si->position + itemLength;
glyphsEnd = si->num_glyphs;
}
// show soft-hyphen at line-break
if (si->position + itemLength >= lineEnd
&& eng->layoutData->string.at(lineEnd - 1) == 0x00ad)
glyphs.attributes[glyphsEnd - 1].dontPrint = false;
itemWidth = 0;
for (int g = glyphsStart; g < glyphsEnd; ++g)
itemWidth += glyphs.effectiveAdvance(g);
return *si;
}
static QFixed offsetInLigature(const unsigned short *logClusters,
const QGlyphLayout &glyphs,
int pos, int max, int glyph_pos)
{
int offsetInCluster = 0;
for (int i = pos - 1; i >= 0; i--) {
if (logClusters[i] == glyph_pos)
offsetInCluster++;
else
break;
}
// in the case that the offset is inside a (multi-character) glyph,
// interpolate the position.
if (offsetInCluster > 0) {
int clusterLength = 0;
for (int i = pos - offsetInCluster; i < max; i++) {
if (logClusters[i] == glyph_pos)
clusterLength++;
else
break;
}
if (clusterLength)
return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
}
return 0;
}
bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const
{
*selectionX = *selectionWidth = 0;
if (!selection)
return false;
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
if (si->position >= selection->start + selection->length
|| si->position + itemLength <= selection->start)
return false;
*selectionX = x;
*selectionWidth = itemWidth;
} else {
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
int from = qMax(itemStart, selection->start) - si->position;
int to = qMin(itemEnd, selection->start + selection->length) - si->position;
if (from >= to)
return false;
int start_glyph = logClusters[from];
int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to];
QFixed soff;
QFixed swidth;
if (si->analysis.bidiLevel %2) {
for (int g = glyphsEnd - 1; g >= end_glyph; --g)
soff += glyphs.effectiveAdvance(g);
for (int g = end_glyph - 1; g >= start_glyph; --g)
swidth += glyphs.effectiveAdvance(g);
} else {
for (int g = glyphsStart; g < start_glyph; ++g)
soff += glyphs.effectiveAdvance(g);
for (int g = start_glyph; g < end_glyph; ++g)
swidth += glyphs.effectiveAdvance(g);
}
// If the starting character is in the middle of a ligature,
// selection should only contain the right part of that ligature
// glyph, so we need to get the width of the left part here and
// add it to *selectionX
QFixed leftOffsetInLigature = offsetInLigature(logClusters, glyphs, from,
to, start_glyph);
*selectionX = x + soff + leftOffsetInLigature;
*selectionWidth = swidth - leftOffsetInLigature;
// If the ending character is also part of a ligature, swidth does
// not contain that part yet, we also need to find out the width of
// that left part
*selectionWidth += offsetInLigature(logClusters, glyphs, to,
eng->length(item), end_glyph);
}
return true;
}
static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPointF &pos, QTextLayout::FormatRange *selection,
QPainterPath *region, QRectF boundingRect)
{
@ -1228,6 +1060,7 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
QRectF lineRect(tl.naturalTextRect());
lineRect.translate(position);
lineRect.adjust(0, 0, d->leadingSpaceWidth(sl).toReal(), 0);
bool isLastLineInBlock = (line == d->lines.size()-1);
int sl_length = sl.length + (isLastLineInBlock? 1 : 0); // the infamous newline
@ -1382,18 +1215,9 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
QFixed pos_y = QFixed::fromReal(position.y());
cursorPosition = qBound(0, cursorPosition, d->layoutData->string.length());
int line = 0;
if (cursorPosition == d->layoutData->string.length()) {
line = d->lines.size() - 1;
} else {
// ### binary search
for (line = 0; line < d->lines.size(); line++) {
const QScriptLine &sl = d->lines[line];
if (sl.from <= cursorPosition && sl.from + (int)sl.length > cursorPosition)
break;
}
}
int line = d->lineNumberForTextPosition(cursorPosition);
if (line < 0)
line = 0;
if (line >= d->lines.size())
return;
@ -1402,7 +1226,15 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
qreal x = position.x() + l.cursorToX(cursorPosition);
int itm = d->findItem(cursorPosition - 1);
int itm;
if (d->visualCursorMovement()) {
if (cursorPosition == sl.from + sl.length)
cursorPosition--;
itm = d->findItem(cursorPosition);
} else
itm = d->findItem(cursorPosition - 1);
QFixed base = sl.base();
QFixed descent = sl.descent;
bool rightToLeft = d->isRightToLeft();
@ -1512,7 +1344,7 @@ QRectF QTextLine::rect() const
QRectF QTextLine::naturalTextRect() const
{
const QScriptLine& sl = eng->lines[i];
QFixed x = sl.x + alignLine(eng, sl);
QFixed x = sl.x + eng->alignLine(sl);
QFixed width = sl.textWidth;
if (sl.justified)
@ -2317,6 +2149,9 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const
QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
glyphLayoutHash.insertMulti(multiFontEngine->engine(which),
GlyphInfo(subLayout, pos, flags));
for (int i = 0; i < subLayout.numGlyphs; i++)
pos += QPointF(subLayout.advances_x[i].toReal(),
subLayout.advances_y[i].toReal());
start = end;
which = e;
@ -2632,9 +2467,10 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
eng->itemize();
const QScriptLine &line = eng->lines[i];
bool lastLine = i >= eng->lines.size() - 1;
QFixed x = line.x;
x += alignLine(eng, line);
x += eng->alignLine(line);
if (!i && !eng->layoutData->items.size()) {
*cursorPos = 0;
@ -2720,21 +2556,29 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
logClusters = eng->logClusters(si);
glyphs = eng->shapedGlyphs(si);
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
if(pos == l)
if (pos == (reverse ? 0 : l))
x += si->width;
} else {
bool rtl = eng->isRightToLeft();
bool visual = eng->visualCursorMovement();
if (reverse) {
int end = qMin(lineEnd, si->position + l) - si->position;
int glyph_end = end == l ? si->num_glyphs : logClusters[end];
for (int i = glyph_end - 1; i >= glyph_pos; i--)
int glyph_start = glyph_pos;
if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem)))
glyph_start++;
for (int i = glyph_end - 1; i >= glyph_start; i--)
x += glyphs.effectiveAdvance(i);
} else {
int start = qMax(line.from - si->position, 0);
int glyph_start = logClusters[start];
for (int i = glyph_start; i < glyph_pos; i++)
int glyph_end = glyph_pos;
if (!visual || !rtl || (lastLine && itm == visualOrder[0] + firstItem))
glyph_end--;
for (int i = glyph_start; i <= glyph_end; i++)
x += glyphs.effectiveAdvance(i);
}
x += offsetInLigature(logClusters, glyphs, pos, line.length, glyph_pos);
x += eng->offsetInLigature(si, pos, line.length, glyph_pos);
}
*cursorPos = pos + si->position;
@ -2753,6 +2597,8 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
{
QFixed x = QFixed::fromReal(_x);
const QScriptLine &line = eng->lines[i];
bool lastLine = i >= eng->lines.size() - 1;
int lineNum = i;
if (!eng->layoutData)
eng->itemize();
@ -2770,7 +2616,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
return 0;
x -= line.x;
x -= alignLine(eng, line);
x -= eng->alignLine(line);
// qDebug("xToCursor: x=%f, cpos=%d", x.toReal(), cpos);
QVarLengthArray<int> visualOrder(nItems);
@ -2779,6 +2625,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
bool visual = eng->visualCursorMovement();
if (x <= 0) {
// left of first item
int item = visualOrder[0]+firstItem;
@ -2795,8 +2642,13 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
|| (line.justified && x < line.width)) {
// has to be in one of the runs
QFixed pos;
bool rtl = eng->isRightToLeft();
eng->shapeLine(line);
QVector<int> insertionPoints;
if (visual && rtl)
eng->insertionPointsForLine(lineNum, insertionPoints);
int nchars = 0;
for (int i = 0; i < nItems; ++i) {
int item = visualOrder[i]+firstItem;
QScriptItem &si = eng->layoutData->items[item];
@ -2826,6 +2678,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
if (pos + item_width < x) {
pos += item_width;
nchars += end;
continue;
}
// qDebug(" inside run");
@ -2870,27 +2723,60 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
} else {
QFixed dist = INT_MAX/256;
if (si.analysis.bidiLevel % 2) {
pos += item_width;
while (gs <= ge) {
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
dist = qAbs(x-pos);
if (!visual || rtl || (lastLine && i == nItems - 1)) {
pos += item_width;
while (gs <= ge) {
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
dist = qAbs(x-pos);
}
pos -= glyphs.effectiveAdvance(gs);
++gs;
}
} else {
while (ge >= gs) {
if (glyphs.attributes[ge].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = ge;
dist = qAbs(x-pos);
}
pos += glyphs.effectiveAdvance(ge);
--ge;
}
pos -= glyphs.effectiveAdvance(gs);
++gs;
}
} else {
while (gs <= ge) {
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
dist = qAbs(x-pos);
if (!visual || !rtl || (lastLine && i == 0)) {
while (gs <= ge) {
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
dist = qAbs(x-pos);
}
pos += glyphs.effectiveAdvance(gs);
++gs;
}
pos += glyphs.effectiveAdvance(gs);
++gs;
} else {
QFixed oldPos = pos;
while (gs <= ge) {
pos += glyphs.effectiveAdvance(gs);
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
dist = qAbs(x-pos);
}
++gs;
}
pos = oldPos;
}
}
if (qAbs(x-pos) < dist)
if (qAbs(x-pos) < dist) {
if (visual) {
if (!rtl && i < nItems - 1) {
nchars += end;
continue;
}
if (rtl && nchars > 0)
return insertionPoints[lastLine ? nchars : nchars - 1];
}
return si.position + end;
}
}
Q_ASSERT(glyph_pos != -1);
int j;

View File

@ -50,6 +50,7 @@
#include <QtGui/qevent.h>
#include <QtGui/qtextformat.h>
#include <QtGui/qglyphs.h>
#include <QtGui/qtextcursor.h>
QT_BEGIN_HEADER
@ -136,6 +137,9 @@ public:
void setCacheEnabled(bool enable);
bool cacheEnabled() const;
void setCursorMoveStyle(QTextCursor::MoveStyle style);
QTextCursor::MoveStyle cursorMoveStyle() const;
void beginLayout();
void endLayout();
void clearLayout();
@ -153,6 +157,8 @@ public:
bool isValidCursorPosition(int pos) const;
int nextCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const;
int previousCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const;
int leftCursorPosition(int oldPos) const;
int rightCursorPosition(int oldPos) const;
void draw(QPainter *p, const QPointF &pos, const QVector<FormatRange> &selections = QVector<FormatRange>(),
const QRectF &clip = QRectF()) const;

View File

@ -114,6 +114,9 @@ unix:x11 {
OBJECTIVE_SOURCES += \
text/qfontengine_coretext.mm \
text/qfontengine_mac.mm
contains(QT_CONFIG, harfbuzz) {
DEFINES += QT_ENABLE_HARFBUZZ_FOR_MAC
}
}
embedded {
@ -136,7 +139,8 @@ qpa {
SOURCES += \
text/qfont_qpa.cpp \
text/qfontengine_qpa.cpp \
text/qplatformfontdatabase_qpa.cpp
text/qplatformfontdatabase_qpa.cpp \
text/qrawfont_qpa.cpp
HEADERS += \
text/qplatformfontdatabase_qpa.h

View File

@ -1585,6 +1585,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
}
bool unknown = false;
bool visual = cursorMoveStyle() == QTextCursor::Visual;
if (false) {
}
@ -1649,11 +1650,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
#endif
moveCursor(selectionEnd(), false);
} else {
cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
}
}
else if (event == QKeySequence::SelectNextChar) {
cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
}
else if (event == QKeySequence::MoveToPreviousChar) {
#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
@ -1664,11 +1665,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
#endif
moveCursor(selectionStart(), false);
} else {
cursorForward(0, layoutDirection() == Qt::LeftToRight ? -1 : 1);
cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
}
}
else if (event == QKeySequence::SelectPreviousChar) {
cursorForward(1, layoutDirection() == Qt::LeftToRight ? -1 : 1);
cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
}
else if (event == QKeySequence::MoveToNextWord) {
if (echoMode() == QLineEdit::Normal)

View File

@ -160,6 +160,8 @@ public:
int cursorWidth() const { return m_cursorWidth; }
void setCursorWidth(int value) { m_cursorWidth = value; }
QTextCursor::MoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
void setCursorMoveStyle(QTextCursor::MoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
void moveCursor(int pos, bool mark = false);
void cursorForward(bool mark, int steps)
@ -167,10 +169,12 @@ public:
int c = m_cursor;
if (steps > 0) {
while (steps--)
c = m_textLayout.nextCursorPosition(c);
c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.rightCursorPosition(c)
: m_textLayout.nextCursorPosition(c);
} else if (steps < 0) {
while (steps++)
c = m_textLayout.previousCursorPosition(c);
c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.leftCursorPosition(c)
: m_textLayout.previousCursorPosition(c);
}
moveCursor(c, mark);
}

View File

@ -1111,6 +1111,34 @@ void QLineEdit::setDragEnabled(bool b)
}
/*!
\property QLineEdit::cursorMoveStyle
\brief the movement style of cursor in this line edit
\since 4.8
When this property is set to QTextCursor::Visual, the line edit will use visual
movement style. Pressing the left arrow key will always cause the cursor to move
left, regardless of the text's writing direction. The same behavior applies to
right arrow key.
When the property is QTextCursor::Logical (the default), within a LTR text block,
increase cursor position when pressing left arrow key, decrease cursor position
when pressing the right arrow key. If the text block is right to left, the opposite
behavior applies.
*/
QTextCursor::MoveStyle QLineEdit::cursorMoveStyle() const
{
Q_D(const QLineEdit);
return d->control->cursorMoveStyle();
}
void QLineEdit::setCursorMoveStyle(QTextCursor::MoveStyle style)
{
Q_D(QLineEdit);
d->control->setCursorMoveStyle(style);
}
/*!
\property QLineEdit::acceptableInput
\brief whether the input satisfies the inputMask and the

View File

@ -43,6 +43,7 @@
#define QLINEEDIT_H
#include <QtGui/qframe.h>
#include <QtGui/qtextcursor.h>
#include <QtCore/qstring.h>
#include <QtCore/qmargins.h>
@ -158,6 +159,9 @@ public:
void setDragEnabled(bool b);
bool dragEnabled() const;
void setCursorMoveStyle(QTextCursor::MoveStyle style);
QTextCursor::MoveStyle cursorMoveStyle() const;
QString inputMask() const;
void setInputMask(const QString &inputMask);
bool hasAcceptableInput() const;

View File

@ -1,12 +1,12 @@
QT_CORE_VERSION = $$QT_VERSION
QT_CORE_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_CORE_MINOR_VERSION = $$QT_MINOR_VERSION
QT_CORE_PATCH_VERSION = $$QT_PATCH_VERSION
QT.core.VERSION = 4.8.0
QT.core.MAJOR_VERSION = 4
QT.core.MINOR_VERSION = 8
QT.core.PATCH_VERSION = 0
QT.core.name = QtCore
QT.core.bins = $$QT_MODULE_BIN_BASE
QT.core.includes = $$QT_MODULE_INCLUDE_BASE/QtCore
QT.core.private_includes = $$QT_MODULE_INCLUDE_BASE/QtCore/private
QT.core.private_includes = $$QT_MODULE_INCLUDE_BASE/QtCore/$$QT.core.VERSION
QT.core.sources = $$QT_MODULE_BASE/src/corelib
QT.core.libs = $$QT_MODULE_LIB_BASE
QT.core.plugins = $$QT_MODULE_PLUGIN_BASE

View File

@ -1,12 +1,12 @@
QT_DBUS_VERSION = $$QT_VERSION
QT_DBUS_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_DBUS_MINOR_VERSION = $$QT_MINOR_VERSION
QT_DBUS_PATCH_VERSION = $$QT_PATCH_VERSION
QT.dbus.VERSION = 4.8.0
QT.dbus.MAJOR_VERSION = 4
QT.dbus.MINOR_VERSION = 8
QT.dbus.PATCH_VERSION = 0
QT.dbus.name = QtDBus
QT.dbus.bins = $$QT_MODULE_BIN_BASE
QT.dbus.includes = $$QT_MODULE_INCLUDE_BASE/QtDBus
QT.dbus.private_includes = $$QT_MODULE_INCLUDE_BASE/QtDBus/private
QT.dbus.private_includes = $$QT_MODULE_INCLUDE_BASE/QtDBus/$$QT.dbus.VERSION
QT.dbus.sources = $$QT_MODULE_BASE/src/dbus
QT.dbus.libs = $$QT_MODULE_LIB_BASE
QT.dbus.plugins = $$QT_MODULE_PLUGIN_BASE

View File

@ -1,11 +1,11 @@
QT_GUI_VERSION = $$QT_VERSION
QT_GUI_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_GUI_MINOR_VERSION = $$QT_MINOR_VERSION
QT_GUI_PATCH_VERSION = $$QT_PATCH_VERSION
QT.gui.VERSION = 4.8.0
QT.gui.MAJOR_VERSION = 4
QT.gui.MINOR_VERSION = 8
QT.gui.PATCH_VERSION = 0
QT.gui.name = QtGui
QT.gui.includes = $$QT_MODULE_INCLUDE_BASE/QtGui
QT.gui.private_includes = $$QT_MODULE_INCLUDE_BASE/QtGui/private
QT.gui.private_includes = $$QT_MODULE_INCLUDE_BASE/QtGui/$$QT.gui.VERSION
QT.gui.sources = $$QT_MODULE_BASE/src/gui
QT.gui.libs = $$QT_MODULE_LIB_BASE
QT.gui.plugins = $$QT_MODULE_PLUGIN_BASE

View File

@ -1,12 +1,12 @@
QT_CORE_VERSION = $$QT_VERSION
QT_NETWORK_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_NETWORK_MINOR_VERSION = $$QT_MINOR_VERSION
QT_NETWORK_PATCH_VERSION = $$QT_PATCH_VERSION
QT.network.VERSION = 4.8.0
QT.network.MAJOR_VERSION = 4
QT.network.MINOR_VERSION = 8
QT.network.PATCH_VERSION = 0
QT.network.name = QtNetwork
QT.network.bins = $$QT_MODULE_BIN_BASE
QT.network.includes = $$QT_MODULE_INCLUDE_BASE/QtNetwork
QT.network.private_includes = $$QT_MODULE_INCLUDE_BASE/QtNetwork/private
QT.network.private_includes = $$QT_MODULE_INCLUDE_BASE/QtNetwork/$$QT.network.VERSION
QT.network.sources = $$QT_MODULE_BASE/src/network
QT.network.libs = $$QT_MODULE_LIB_BASE
QT.network.plugins = $$QT_MODULE_PLUGIN_BASE

View File

@ -1,12 +1,12 @@
QT_OPENGL_VERSION = $$QT_VERSION
QT_OPENGL_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_OPENGL_MINOR_VERSION = $$QT_MINOR_VERSION
QT_OPENGL_PATCH_VERSION = $$QT_PATCH_VERSION
QT.opengl.VERSION = 4.8.0
QT.opengl.MAJOR_VERSION = 4
QT.opengl.MINOR_VERSION = 8
QT.opengl.PATCH_VERSION = 0
QT.opengl.name = QtOpenGL
QT.opengl.bins = $$QT_MODULE_BIN_BASE
QT.opengl.includes = $$QT_MODULE_INCLUDE_BASE/QtOpenGL
QT.opengl.private_includes = $$QT_MODULE_INCLUDE_BASE/QtOpenGL/private
QT.opengl.private_includes = $$QT_MODULE_INCLUDE_BASE/QtOpenGL/$$QT.opengl.VERSION
QT.opengl.sources = $$QT_MODULE_BASE/src/opengl
QT.opengl.libs = $$QT_MODULE_LIB_BASE
QT.opengl.plugins = $$QT_MODULE_PLUGIN_BASE

View File

@ -1,12 +1,12 @@
QT_OPENVG_VERSION = $$QT_VERSION
QT_OPENVG_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_OPENVG_MINOR_VERSION = $$QT_MINOR_VERSION
QT_OPENVG_PATCH_VERSION = $$QT_PATCH_VERSION
QT.openvg.VERSION = 4.8.0
QT.openvg.MAJOR_VERSION = 4
QT.openvg.MINOR_VERSION = 8
QT.openvg.PATCH_VERSION = 0
QT.openvg.name = QtOpenVG
QT.openvg.bins = $$QT_MODULE_BIN_BASE
QT.openvg.includes = $$QT_MODULE_INCLUDE_BASE/QtOpenVG
QT.openvg.private_includes = $$QT_MODULE_INCLUDE_BASE/QtOpenVG/private
QT.openvg.private_includes = $$QT_MODULE_INCLUDE_BASE/QtOpenVG/$$QT.openvg.VERSION
QT.openvg.sources = $$QT_MODULE_BASE/src/openvg
QT.openvg.libs = $$QT_MODULE_LIB_BASE
QT.openvg.plugins = $$QT_MODULE_PLUGIN_BASE

View File

@ -1,12 +1,12 @@
QT_SQL_VERSION = $$QT_VERSION
QT_SQL_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_SQL_MINOR_VERSION = $$QT_MINOR_VERSION
QT_SQL_PATCH_VERSION = $$QT_PATCH_VERSION
QT.sql.VERSION = 4.8.0
QT.sql.MAJOR_VERSION = 4
QT.sql.MINOR_VERSION = 8
QT.sql.PATCH_VERSION = 0
QT.sql.name = QtSql
QT.sql.bins = $$QT_MODULE_BIN_BASE
QT.sql.includes = $$QT_MODULE_INCLUDE_BASE/QtSql
QT.sql.private_includes = $$QT_MODULE_INCLUDE_BASE/QtSql/private
QT.sql.private_includes = $$QT_MODULE_INCLUDE_BASE/QtSql/$$QT.sql.VERSION
QT.sql.sources = $$QT_MODULE_BASE/src/sql
QT.sql.libs = $$QT_MODULE_LIB_BASE
QT.sql.plugins = $$QT_MODULE_PLUGIN_BASE

View File

@ -1,12 +1,12 @@
QT_TEST_VERSION = $$QT_VERSION
QT_TEST_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_TEST_MINOR_VERSION = $$QT_MINOR_VERSION
QT_TEST_PATCH_VERSION = $$QT_PATCH_VERSION
QT.testlib.VERSION = 4.8.0
QT.testlib.MAJOR_VERSION = 4
QT.testlib.MINOR_VERSION = 8
QT.testlib.PATCH_VERSION = 0
QT.testlib.name = QtTest
QT.testlib.bins = $$QT_MODULE_BIN_BASE
QT.testlib.includes = $$QT_MODULE_INCLUDE_BASE/QtTest
QT.testlib.private_includes = $$QT_MODULE_INCLUDE_BASE/QtTest/private
QT.testlib.private_includes = $$QT_MODULE_INCLUDE_BASE/QtTest/$$QT.testlib.VERSION
QT.testlib.sources = $$QT_MODULE_BASE/src/testlib
QT.testlib.libs = $$QT_MODULE_LIB_BASE
QT.testlib.plugins = $$QT_MODULE_PLUGIN_BASE

View File

@ -1,14 +1,13 @@
QT_UILIB_VERSION = $$QT_VERSION
QT_UILIB_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_UILIB_MINOR_VERSION = $$QT_MINOR_VERSION
QT_UILIB_PATCH_VERSION = $$QT_PATCH_VERSION
QT.uilib.VERSION = 4.8.0
QT.uilib.MAJOR_VERSION = 4
QT.uilib.MINOR_VERSION = 8
QT.uilib.PATCH_VERSION = 0
QT.uilib.name =
QT.uilib.name = QtUiLib
QT.uilib.bins = $$QT_MODULE_BIN_BASE
QT.uilib.includes = $$QT_MODULE_INCLUDE_BASE/QtDesigner
QT.uilib.private_includes = $$QT_MODULE_INCLUDE_BASE/QtDesigner/private
QT.uilib.private_includes = $$QT_MODULE_INCLUDE_BASE/QtDesigner/$$QT.uilib.VERSION
QT.uilib.sources = $$QT_MODULE_BASE/tools/uilib
QT.uilib.libs = $$QT_MODULE_LIB_BASE
QT.uilib.plugins = $$QT_MODULE_PLUGIN_BASE
QT.uilib.imports = $$QT_MODULE_IMPORT_BASE
QT.uilib.depends = xml

View File

@ -1,12 +1,12 @@
QT_UITOOLS_VERSION = $$QT_VERSION
QT_UITOOLS_MAJOR_VERSION = $$QT_MAJOR_VERSION
QT_UITOOLS_MINOR_VERSION = $$QT_MINOR_VERSION
QT_UITOOLS_PATCH_VERSION = $$QT_PATCH_VERSION
QT.uitools.VERSION = 4.8.0
QT.uitools.MAJOR_VERSION = 4
QT.uitools.MINOR_VERSION = 8
QT.uitools.PATCH_VERSION = 0
QT.uitools.name = QtUiTools
QT.uitools.bins = $$QT_MODULE_BIN_BASE
QT.uitools.includes = $$QT_MODULE_INCLUDE_BASE/QtUiTools
QT.uitools.private_includes = $$QT_MODULE_INCLUDE_BASE/QtUiTools/private
QT.uitools.private_includes = $$QT_MODULE_INCLUDE_BASE/QtUiTools/$$QT.uitools.VERSION
QT.uitools.sources = $$QT_MODULE_BASE/src/uitools
QT.uitools.libs = $$QT_MODULE_LIB_BASE
QT.uitools.plugins = $$QT_MODULE_PLUGIN_BASE

Some files were not shown because too many files have changed in this diff Show More