summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-05-31 13:49:01 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-05-31 13:49:01 +0200
commit289da5616df56912fa6f8c319d61fb4489c51add (patch)
treee3ec954e4b8111cf24c13d3a158ff9038cd42389
parentd7b8c69ccdd5547b5660be5876dbdedc3ac29548 (diff)
parentac00a345b23686aa458539dde0cb3711bed84de3 (diff)
downloadqtwebkit-289da5616df56912fa6f8c319d61fb4489c51add.tar.gz
Merge remote-tracking branch 'origin/release' into stable
Change-Id: I7ef48469c216c57f048d21887abc5d10619fab4b
-rw-r--r--Source/WebCore/platform/graphics/Font.cpp24
-rw-r--r--Source/WebCore/platform/graphics/FontFastPath.cpp102
-rw-r--r--Source/WebCore/platform/graphics/GlyphBuffer.h10
-rw-r--r--Source/WebCore/platform/graphics/WidthIterator.cpp23
-rw-r--r--Source/WebCore/platform/graphics/WidthIterator.h2
-rw-r--r--Source/WebKit/qt/declarative/plugins.qmltypes199
-rw-r--r--Source/WebKit/qt/declarative/qmldir1
7 files changed, 281 insertions, 80 deletions
diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp
index f55725e67..42dd14a6b 100644
--- a/Source/WebCore/platform/graphics/Font.cpp
+++ b/Source/WebCore/platform/graphics/Font.cpp
@@ -166,12 +166,7 @@ void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoi
to = (to == -1 ? run.length() : to);
- CodePath codePathToUse = codePath(run);
- // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
- if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()))
- codePathToUse = Complex;
-
- if (codePathToUse != Complex)
+ if (codePath(run) != Complex)
return drawSimpleText(context, run, point, from, to);
return drawComplexText(context, run, point, from, to);
@@ -185,12 +180,7 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const
if (to < 0)
to = run.length();
- CodePath codePathToUse = codePath(run);
- // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
- if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()))
- codePathToUse = Complex;
-
- if (codePathToUse != Complex)
+ if (codePath(run) != Complex)
drawEmphasisMarksForSimpleText(context, run, mark, point, from, to);
else
drawEmphasisMarksForComplexText(context, run, mark, point, from, to);
@@ -260,12 +250,7 @@ FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point
{
to = (to == -1 ? run.length() : to);
- CodePath codePathToUse = codePath(run);
- // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
- if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()))
- codePathToUse = Complex;
-
- if (codePathToUse != Complex)
+ if (codePath(run) != Complex)
return selectionRectForSimpleText(run, point, h, from, to);
return selectionRectForComplexText(run, point, h, from, to);
@@ -273,8 +258,7 @@ FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point
int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const
{
- // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
- if (codePath(run) != Complex && !typesettingFeatures())
+ if (codePath(run) != Complex)
return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
return offsetForPositionForComplexText(run, x, includePartialGlyphs);
diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp
index 7ed7a9703..22ce7f57e 100644
--- a/Source/WebCore/platform/graphics/FontFastPath.cpp
+++ b/Source/WebCore/platform/graphics/FontFastPath.cpp
@@ -325,32 +325,34 @@ int Font::emphasisMarkHeight(const AtomicString& mark) const
float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
{
- float initialAdvance;
-
WidthIterator it(this, run, 0, false, forTextEmphasis);
- // FIXME: Using separate glyph buffers for the prefix and the suffix is incorrect when kerning or
- // ligatures are enabled.
GlyphBuffer localGlyphBuffer;
- it.advance(from, &localGlyphBuffer);
- float beforeWidth = it.m_runWidthSoFar;
- it.advance(to, &glyphBuffer);
+ it.advance(run.length(), &localGlyphBuffer);
- if (glyphBuffer.isEmpty())
+ if (localGlyphBuffer.isEmpty())
return 0;
- float afterWidth = it.m_runWidthSoFar;
+ float totalWidth = it.m_runWidthSoFar;
+ float beforeWidth = 0;
+ int glyphPos = 0;
+ for (; glyphPos < localGlyphBuffer.size() && it.m_characterIndex[glyphPos] < from; ++glyphPos)
+ beforeWidth += localGlyphBuffer.advanceAt(glyphPos);
+ int glyphFrom = glyphPos;
- if (run.rtl()) {
- float finalRoundingWidth = it.m_finalRoundingWidth;
- it.advance(run.length(), &localGlyphBuffer);
- initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
- } else
- initialAdvance = beforeWidth;
+ float afterWidth = totalWidth;
+ glyphPos = localGlyphBuffer.size() - 1;
+ for (; glyphPos >= glyphFrom && it.m_characterIndex[glyphPos] >= to; --glyphPos)
+ afterWidth -= localGlyphBuffer.advanceAt(glyphPos);
+ int glyphTo = glyphPos + 1;
+
+ glyphBuffer.add(&localGlyphBuffer, glyphFrom, glyphTo - glyphFrom);
- if (run.rtl())
+ if (run.rtl()) {
glyphBuffer.reverse(0, glyphBuffer.size());
+ return totalWidth - afterWidth;
+ }
- return initialAdvance;
+ return beforeWidth;
}
void Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
@@ -487,15 +489,22 @@ FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint&
{
GlyphBuffer glyphBuffer;
WidthIterator it(this, run);
- it.advance(from, &glyphBuffer);
- float beforeWidth = it.m_runWidthSoFar;
- it.advance(to, &glyphBuffer);
- float afterWidth = it.m_runWidthSoFar;
+ it.advance(run.length(), &glyphBuffer);
+
+ float totalWidth = it.m_runWidthSoFar;
+ float beforeWidth = 0;
+ int glyphPos = 0;
+ for (; glyphPos < glyphBuffer.size() && it.m_characterIndex[glyphPos] < from; ++glyphPos)
+ beforeWidth += glyphBuffer.advanceAt(glyphPos);
+ int glyphFrom = glyphPos;
+
+ float afterWidth = totalWidth;
+ glyphPos = glyphBuffer.size() - 1;
+ for (; glyphPos >= glyphFrom && it.m_characterIndex[glyphPos] >= to; --glyphPos)
+ afterWidth -= glyphBuffer.advanceAt(glyphPos);
// Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning.
if (run.rtl()) {
- it.advance(run.length(), &glyphBuffer);
- float totalWidth = it.m_runWidthSoFar;
return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h);
}
@@ -504,45 +513,50 @@ FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint&
int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool includePartialGlyphs) const
{
- float delta = x;
-
+ GlyphBuffer glyphBuffer;
WidthIterator it(this, run);
- GlyphBuffer localGlyphBuffer;
- unsigned offset;
+ it.advance(run.length(), &glyphBuffer);
+
+ int characterOffset = 0;
if (run.rtl()) {
- delta -= floatWidthForSimpleText(run);
- while (1) {
- offset = it.m_currentCharacter;
- float w;
- if (!it.advanceOneCharacter(w, localGlyphBuffer))
+ float currentX = it.m_runWidthSoFar;
+ for (int glyphPosition = 0; glyphPosition <= glyphBuffer.size(); ++glyphPosition) {
+ if (glyphPosition == glyphBuffer.size()) {
+ characterOffset = run.length();
break;
- delta += w;
+ }
+ characterOffset = it.m_characterIndex[glyphPosition];
+ float glyphWidth = glyphBuffer.advanceAt(glyphPosition);
if (includePartialGlyphs) {
- if (delta - w / 2 >= 0)
+ if (currentX - glyphWidth / 2.0f <= x)
break;
} else {
- if (delta >= 0)
+ if (currentX - glyphWidth <= x)
break;
}
+ currentX -= glyphWidth;
}
} else {
- while (1) {
- offset = it.m_currentCharacter;
- float w;
- if (!it.advanceOneCharacter(w, localGlyphBuffer))
+ float currentX = 0;
+ for (int glyphPosition = 0; glyphPosition <= glyphBuffer.size(); ++glyphPosition) {
+ if (glyphPosition == glyphBuffer.size()) {
+ characterOffset = run.length();
break;
- delta -= w;
+ }
+ characterOffset = it.m_characterIndex[glyphPosition];
+ float glyphWidth = glyphBuffer.advanceAt(glyphPosition);
if (includePartialGlyphs) {
- if (delta + w / 2 <= 0)
+ if (currentX + glyphWidth / 2.0f >= x)
break;
} else {
- if (delta <= 0)
+ if (currentX + glyphWidth >= x)
break;
}
+ currentX += glyphWidth;
}
}
- return offset;
+ return characterOffset;
}
-}
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/GlyphBuffer.h b/Source/WebCore/platform/graphics/GlyphBuffer.h
index 3aec08e65..9d757bc20 100644
--- a/Source/WebCore/platform/graphics/GlyphBuffer.h
+++ b/Source/WebCore/platform/graphics/GlyphBuffer.h
@@ -153,6 +153,16 @@ public:
#endif
}
+ void add(const GlyphBuffer* glyphBuffer, int from, int len)
+ {
+ m_glyphs.append(glyphBuffer->glyphs(from), len);
+ m_advances.append(glyphBuffer->advances(from), len);
+ m_fontData.append(glyphBuffer->m_fontData.data() + from, len);
+#if PLATFORM(WIN)
+ m_offsets.append(glyphBuffer->m_offsets.data() + from, len);
+#endif
+ }
+
void add(Glyph glyph, const SimpleFontData* font, float width, const FloatSize* offset = 0)
{
m_fontData.append(font);
diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp
index 96600c732..1fb1d9b40 100644
--- a/Source/WebCore/platform/graphics/WidthIterator.cpp
+++ b/Source/WebCore/platform/graphics/WidthIterator.cpp
@@ -162,7 +162,8 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
CharactersTreatedAsSpace charactersTreatedAsSpace;
while (textIterator.consume(character, clusterLength)) {
unsigned advanceLength = clusterLength;
- const GlyphData& glyphData = glyphDataForCharacter(character, rtl, textIterator.currentCharacter(), advanceLength);
+ int currentCharacterIndex = textIterator.currentCharacter();
+ const GlyphData& glyphData = glyphDataForCharacter(character, rtl, currentCharacterIndex, advanceLength);
Glyph glyph = glyphData.glyph;
const SimpleFontData* fontData = glyphData.fontData;
@@ -223,9 +224,10 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
float expansionAtThisOpportunity = !m_run.applyWordRounding() ? m_expansionPerOpportunity : roundf(previousExpansion) - roundf(m_expansion);
m_runWidthSoFar += expansionAtThisOpportunity;
if (glyphBuffer) {
- if (glyphBuffer->isEmpty())
+ if (glyphBuffer->isEmpty()) {
glyphBuffer->add(fontData->spaceGlyph(), fontData, expansionAtThisOpportunity);
- else
+ m_characterIndex.append(currentCharacterIndex);
+ } else
glyphBuffer->expandLastAdvance(expansionAtThisOpportunity);
}
previousExpansion = m_expansion;
@@ -291,8 +293,10 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
widthSinceLastRounding += width;
}
- if (glyphBuffer)
+ if (glyphBuffer) {
glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width));
+ m_characterIndex.append(currentCharacterIndex);
+ }
lastRoundingWidth = width - oldWidth;
@@ -332,15 +336,4 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
return advanceInternal(textIterator, glyphBuffer);
}
-bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer& glyphBuffer)
-{
- int oldSize = glyphBuffer.size();
- advance(m_currentCharacter + 1, &glyphBuffer);
- float w = 0;
- for (int i = oldSize; i < glyphBuffer.size(); ++i)
- w += glyphBuffer.advanceAt(i);
- width = w;
- return glyphBuffer.size() > oldSize;
-}
-
}
diff --git a/Source/WebCore/platform/graphics/WidthIterator.h b/Source/WebCore/platform/graphics/WidthIterator.h
index 8e4e06997..6dc1c206c 100644
--- a/Source/WebCore/platform/graphics/WidthIterator.h
+++ b/Source/WebCore/platform/graphics/WidthIterator.h
@@ -43,7 +43,6 @@ public:
WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false, bool forTextEmphasis = false);
unsigned advance(int to, GlyphBuffer*);
- bool advanceOneCharacter(float& width, GlyphBuffer&);
float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; }
float minGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_minGlyphBoundingBoxY; }
@@ -83,6 +82,7 @@ public:
float m_expansionPerOpportunity;
bool m_isAfterExpansion;
float m_finalRoundingWidth;
+ Vector<int> m_characterIndex;
#if ENABLE(SVG_FONTS)
String m_lastGlyphName;
diff --git a/Source/WebKit/qt/declarative/plugins.qmltypes b/Source/WebKit/qt/declarative/plugins.qmltypes
new file mode 100644
index 000000000..9532916b9
--- /dev/null
+++ b/Source/WebKit/qt/declarative/plugins.qmltypes
@@ -0,0 +1,199 @@
+import QtQuick.tooling 1.1
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated with the command 'qmlplugindump -noinstantiate -nonrelocatable QtWebKit 3.0'.
+
+Module {
+ Component {
+ name: "QIODevice"
+ prototype: "QObject"
+ Signal { name: "readyRead" }
+ Signal {
+ name: "bytesWritten"
+ Parameter { name: "bytes"; type: "qlonglong" }
+ }
+ Signal { name: "aboutToClose" }
+ Signal { name: "readChannelFinished" }
+ }
+ Component {
+ name: "QNetworkReply"
+ prototype: "QIODevice"
+ exports: ["QtWebKit/NetworkReply 3.0"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "NetworkError"
+ values: {
+ "NoError": 0,
+ "ConnectionRefusedError": 1,
+ "RemoteHostClosedError": 2,
+ "HostNotFoundError": 3,
+ "TimeoutError": 4,
+ "OperationCanceledError": 5,
+ "SslHandshakeFailedError": 6,
+ "TemporaryNetworkFailureError": 7,
+ "NetworkSessionFailedError": 8,
+ "BackgroundRequestNotAllowedError": 9,
+ "UnknownNetworkError": 99,
+ "ProxyConnectionRefusedError": 101,
+ "ProxyConnectionClosedError": 102,
+ "ProxyNotFoundError": 103,
+ "ProxyTimeoutError": 104,
+ "ProxyAuthenticationRequiredError": 105,
+ "UnknownProxyError": 199,
+ "ContentAccessDenied": 201,
+ "ContentOperationNotPermittedError": 202,
+ "ContentNotFoundError": 203,
+ "AuthenticationRequiredError": 204,
+ "ContentReSendError": 205,
+ "UnknownContentError": 299,
+ "ProtocolUnknownError": 301,
+ "ProtocolInvalidOperationError": 302,
+ "ProtocolFailure": 399
+ }
+ }
+ Signal { name: "metaDataChanged" }
+ Signal { name: "finished" }
+ Signal {
+ name: "error"
+ Parameter { type: "QNetworkReply::NetworkError" }
+ }
+ Signal { name: "encrypted" }
+ Signal {
+ name: "sslErrors"
+ Parameter { name: "errors"; type: "QList<QSslError>" }
+ }
+ Signal {
+ name: "uploadProgress"
+ Parameter { name: "bytesSent"; type: "qlonglong" }
+ Parameter { name: "bytesTotal"; type: "qlonglong" }
+ }
+ Signal {
+ name: "downloadProgress"
+ Parameter { name: "bytesReceived"; type: "qlonglong" }
+ Parameter { name: "bytesTotal"; type: "qlonglong" }
+ }
+ Method { name: "abort" }
+ Method { name: "ignoreSslErrors" }
+ }
+ Component {
+ name: "QQuickWebPage"
+ defaultProperty: "data"
+ prototype: "QQuickItem"
+ exports: ["QtWebKit/WebPage 3.0"]
+ exportMetaObjectRevisions: [0]
+ }
+ Component {
+ name: "QQuickWebView"
+ defaultProperty: "flickableData"
+ prototype: "QQuickFlickable"
+ exports: ["QtWebKit/WebView 3.0"]
+ exportMetaObjectRevisions: [0]
+ attachedType: "QQuickWebViewAttached"
+ Enum {
+ name: "NavigationRequestAction"
+ values: {
+ "AcceptRequest": 0,
+ "IgnoreRequest": 255
+ }
+ }
+ Enum {
+ name: "LoadStatus"
+ values: {
+ "LoadStartedStatus": 0,
+ "LoadStoppedStatus": 1,
+ "LoadSucceededStatus": 2,
+ "LoadFailedStatus": 3
+ }
+ }
+ Enum {
+ name: "ErrorDomain"
+ values: {
+ "NoErrorDomain": 0,
+ "InternalErrorDomain": 1,
+ "NetworkErrorDomain": 2,
+ "HttpErrorDomain": 3,
+ "DownloadErrorDomain": 4
+ }
+ }
+ Enum {
+ name: "NavigationType"
+ values: {
+ "LinkClickedNavigation": 0,
+ "FormSubmittedNavigation": 1,
+ "BackForwardNavigation": 2,
+ "ReloadNavigation": 3,
+ "FormResubmittedNavigation": 4,
+ "OtherNavigation": 5
+ }
+ }
+ Property { name: "title"; type: "string"; isReadonly: true }
+ Property { name: "url"; type: "QUrl" }
+ Property { name: "icon"; type: "QUrl"; isReadonly: true }
+ Property { name: "canGoBack"; type: "bool"; isReadonly: true }
+ Property { name: "canGoForward"; type: "bool"; isReadonly: true }
+ Property { name: "loading"; type: "bool"; isReadonly: true }
+ Property { name: "loadProgress"; type: "int"; isReadonly: true }
+ Signal { name: "navigationHistoryChanged" }
+ Signal {
+ name: "loadingChanged"
+ Parameter { name: "loadRequest"; type: "QWebLoadRequest"; isPointer: true }
+ }
+ Signal {
+ name: "linkHovered"
+ Parameter { name: "hoveredUrl"; type: "QUrl" }
+ Parameter { name: "hoveredTitle"; type: "string" }
+ }
+ Signal {
+ name: "navigationRequested"
+ Parameter { name: "request"; type: "QWebNavigationRequest"; isPointer: true }
+ }
+ Method {
+ name: "loadHtml"
+ Parameter { name: "html"; type: "string" }
+ Parameter { name: "baseUrl"; type: "QUrl" }
+ Parameter { name: "unreachableUrl"; type: "QUrl" }
+ }
+ Method {
+ name: "loadHtml"
+ Parameter { name: "html"; type: "string" }
+ Parameter { name: "baseUrl"; type: "QUrl" }
+ }
+ Method {
+ name: "loadHtml"
+ Parameter { name: "html"; type: "string" }
+ }
+ Method { name: "goBack" }
+ Method { name: "goForward" }
+ Method { name: "stop" }
+ Method { name: "reload" }
+ }
+ Component {
+ name: "QQuickWebViewAttached"
+ prototype: "QObject"
+ Property { name: "view"; type: "QQuickWebView"; isReadonly: true; isPointer: true }
+ }
+ Component {
+ name: "QWebLoadRequest"
+ prototype: "QObject"
+ exports: ["QtWebKit/WebLoadRequest 3.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "url"; type: "QUrl"; isReadonly: true }
+ Property { name: "status"; type: "QQuickWebView::LoadStatus"; isReadonly: true }
+ Property { name: "errorString"; type: "string"; isReadonly: true }
+ Property { name: "errorDomain"; type: "QQuickWebView::ErrorDomain"; isReadonly: true }
+ Property { name: "errorCode"; type: "int"; isReadonly: true }
+ }
+ Component {
+ name: "QWebNavigationRequest"
+ prototype: "QObject"
+ exports: ["QtWebKit/NavigationRequest 3.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "url"; type: "QUrl"; isReadonly: true }
+ Property { name: "mouseButton"; type: "int"; isReadonly: true }
+ Property { name: "keyboardModifiers"; type: "int"; isReadonly: true }
+ Property { name: "action"; type: "QQuickWebView::NavigationRequestAction" }
+ Property { name: "navigationType"; type: "QQuickWebView::NavigationType"; isReadonly: true }
+ }
+}
diff --git a/Source/WebKit/qt/declarative/qmldir b/Source/WebKit/qt/declarative/qmldir
index b9c5d05dc..962e92f06 100644
--- a/Source/WebKit/qt/declarative/qmldir
+++ b/Source/WebKit/qt/declarative/qmldir
@@ -1,2 +1,3 @@
module QtWebKit
plugin qmlwebkitplugin
+typeinfo plugins.qmltypes