summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/ScrollView.cpp62
-rw-r--r--WebCore/platform/ScrollView.h14
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h2
-rw-r--r--WebCore/platform/graphics/android/BaseLayerAndroid.cpp2
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp8
-rw-r--r--WebCore/platform/graphics/android/GLUtils.cpp12
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp11
-rw-r--r--WebCore/platform/graphics/android/ShaderProgram.cpp24
-rw-r--r--WebCore/platform/graphics/android/ShaderProgram.h4
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.cpp1
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp22
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.h2
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp7
-rw-r--r--WebCore/platform/mac/ScrollViewMac.mm9
-rw-r--r--WebCore/platform/network/FormData.cpp10
15 files changed, 132 insertions, 58 deletions
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 57fbaa1..4f83794 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -54,6 +54,7 @@ ScrollView::ScrollView()
, m_useFixedLayout(false)
, m_paintsEntireContents(false)
, m_delegatesScrolling(false)
+ , m_scrollOriginX(0)
{
platformInit();
}
@@ -308,9 +309,21 @@ int ScrollView::actualScrollY() const
IntPoint ScrollView::maximumScrollPosition() const
{
- IntSize maximumOffset = contentsSize() - visibleContentRect().size();
+ IntPoint maximumOffset(contentsWidth() - visibleWidth() - m_scrollOriginX, contentsHeight() - visibleHeight());
maximumOffset.clampNegativeToZero();
- return IntPoint(maximumOffset.width(), maximumOffset.height());
+ return maximumOffset;
+}
+
+IntPoint ScrollView::minimumScrollPosition() const
+{
+ return IntPoint(-m_scrollOriginX, 0);
+}
+
+IntPoint ScrollView::adjustScrollPositionWithinRange(const IntPoint& scrollPoint) const
+{
+ IntPoint newScrollPosition = scrollPoint.shrunkTo(maximumScrollPosition());
+ newScrollPosition = newScrollPosition.expandedTo(minimumScrollPosition());
+ return newScrollPosition;
}
int ScrollView::scrollSize(ScrollbarOrientation orientation) const
@@ -333,7 +346,7 @@ void ScrollView::valueChanged(Scrollbar* scrollbar)
IntSize newOffset = m_scrollOffset;
if (scrollbar) {
if (scrollbar->orientation() == HorizontalScrollbar)
- newOffset.setWidth(scrollbar->value());
+ newOffset.setWidth(scrollbar->value() - m_scrollOriginX);
else if (scrollbar->orientation() == VerticalScrollbar)
newOffset.setHeight(scrollbar->value());
}
@@ -378,8 +391,7 @@ void ScrollView::setScrollPosition(const IntPoint& scrollPoint)
}
#endif
- IntPoint newScrollPosition = scrollPoint.shrunkTo(maximumScrollPosition());
- newScrollPosition.clampNegativeToZero();
+ IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
if (newScrollPosition == scrollPosition())
return;
@@ -500,10 +512,10 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
return;
m_inUpdateScrollbars = true;
- IntSize maxScrollPosition(contentsWidth() - visibleWidth(), contentsHeight() - visibleHeight());
- IntSize scroll = desiredOffset.shrunkTo(maxScrollPosition);
- scroll.clampNegativeToZero();
-
+
+ IntPoint scrollPoint = adjustScrollPositionWithinRange(IntPoint(desiredOffset.width(), desiredOffset.height()));
+ IntSize scroll(scrollPoint.x(), scrollPoint.y());
+
if (m_horizontalScrollbar) {
int clientWidth = visibleWidth();
m_horizontalScrollbar->setEnabled(contentsWidth() > clientWidth);
@@ -521,7 +533,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
m_horizontalScrollbar->setSuppressInvalidation(true);
m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_horizontalScrollbar->setProportion(clientWidth, contentsWidth());
- m_horizontalScrollbar->setValue(scroll.width(), Scrollbar::NotFromScrollAnimator);
+ m_horizontalScrollbar->setValue(scroll.width() + m_scrollOriginX, Scrollbar::NotFromScrollAnimator);
if (m_scrollbarsSuppressed)
m_horizontalScrollbar->setSuppressInvalidation(false);
}
@@ -748,11 +760,12 @@ void ScrollView::wheelEvent(PlatformWheelEvent& e)
// scroll any further.
float deltaX = m_horizontalScrollbar ? e.deltaX() : 0;
float deltaY = m_verticalScrollbar ? e.deltaY() : 0;
- IntSize maxScrollDelta = maximumScrollPosition() - scrollPosition();
- if ((deltaX < 0 && maxScrollDelta.width() > 0)
- || (deltaX > 0 && scrollOffset().width() > 0)
- || (deltaY < 0 && maxScrollDelta.height() > 0)
- || (deltaY > 0 && scrollOffset().height() > 0)) {
+ IntSize maxForwardScrollDelta = maximumScrollPosition() - scrollPosition();
+ IntSize maxBackwardScrollDelta = scrollPosition() - minimumScrollPosition();
+ if ((deltaX < 0 && maxForwardScrollDelta.width() > 0)
+ || (deltaX > 0 && maxBackwardScrollDelta.width() >0)
+ || (deltaY < 0 && maxForwardScrollDelta.height() > 0)
+ || (deltaY > 0 && maxBackwardScrollDelta.height() > 0)) {
e.accept();
if (e.granularity() == ScrollByPageWheelEvent) {
ASSERT(!e.deltaX());
@@ -1048,6 +1061,21 @@ void ScrollView::removePanScrollIcon()
hostWindow()->invalidateContentsAndWindow(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)), true /*immediate*/);
}
+void ScrollView::setScrollOriginX(int x)
+{
+ if (platformWidget())
+ platformSetScrollOriginX(x);
+
+ m_scrollOriginX = x;
+}
+
+void ScrollView::updateScrollbars()
+{
+ if (!platformWidget())
+ updateScrollbars(scrollOffset());
+ // FIXME: need corresponding functionality from platformWidget.
+}
+
#if !PLATFORM(WX) && !PLATFORM(GTK) && !PLATFORM(EFL)
void ScrollView::platformInit()
@@ -1078,6 +1106,10 @@ void ScrollView::platformSetScrollbarsSuppressed(bool)
{
}
+void ScrollView::platformSetScrollOriginX(int)
+{
+}
+
#endif
#if !PLATFORM(MAC) && !PLATFORM(WX)
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 660cfc6..3627283 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -167,6 +167,9 @@ public:
IntPoint scrollPosition() const { return visibleContentRect().location(); }
IntSize scrollOffset() const { return visibleContentRect().location() - IntPoint(); } // Gets the scrolled position as an IntSize. Convenient for adding to other sizes.
IntPoint maximumScrollPosition() const; // The maximum position we can be scrolled to.
+ IntPoint minimumScrollPosition() const; // The minimum position we can be scrolled to.
+ // Adjust the pass in scroll position within the minimum and maximum positions.
+ IntPoint adjustScrollPositionWithinRange(const IntPoint&) const;
int scrollX() const { return scrollPosition().x(); }
int scrollY() const { return scrollPosition().y(); }
@@ -286,6 +289,10 @@ protected:
// Scroll the content by invalidating everything.
virtual void scrollContentsSlowPath(const IntRect& updateRect);
+ void setScrollOriginX(int);
+ int scrollOriginX() { return m_scrollOriginX; }
+ void updateScrollbars();
+
private:
RefPtr<Scrollbar> m_horizontalScrollbar;
RefPtr<Scrollbar> m_verticalScrollbar;
@@ -321,6 +328,11 @@ private:
bool m_paintsEntireContents;
bool m_delegatesScrolling;
+ // m_scrollOriginX is 0 for LTR page. And it is negative of left layout
+ // overflow for RTL page. It is mainly used to set the horizontal scrollbar
+ // position for RTL page.
+ int m_scrollOriginX;
+
void init();
void destroy();
@@ -348,6 +360,8 @@ private:
void platformSetScrollbarsSuppressed(bool repaintOnUnsuppress);
void platformRepaintContentRectangle(const IntRect&, bool now);
bool platformIsOffscreen() const;
+
+ void platformSetScrollOriginX(int);
#if PLATFORM(ANDROID)
int platformActualWidth() const;
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index 8ca6434..ab68997 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -239,6 +239,8 @@ namespace WebCore {
// StatsCounters ------------------------------------------------------
static void decrementStatsCounter(const char* name);
static void incrementStatsCounter(const char* name);
+ static void histogramCustomCounts(const char* name, int sample, int min, int max, int bucketCount);
+ static void histogramEnumeration(const char* name, int sample, int boundaryValue);
// Sudden Termination
static void suddenTerminationChanged(bool enabled);
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index 1a08b3c..5a26868 100644
--- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -250,7 +250,7 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect,
(float)m_color.blue() / 255.0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glViewport(left, top, width, height);
ShaderProgram* shader = TilesManager::instance()->shader();
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index 789cbe0..a506ac9 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -172,8 +172,12 @@ void BaseTile::draw(float transparency, SkRect& rect)
bool usable = m_usable;
bool isTexturePainted = m_lastPaintedPicture;
m_atomicSync.unlock();
- if (!usable || !isTexturePainted) {
- XLOG("early return at BaseTile::draw b/c tile set to unusable or not painted !");
+ if (!usable) {
+ XLOG("early return at BaseTile::draw b/c tile set to unusable !");
+ return;
+ }
+ if (!isTexturePainted) {
+ XLOG("early return at BaseTile::draw b/c tile is not painted !");
return;
}
diff --git a/WebCore/platform/graphics/android/GLUtils.cpp b/WebCore/platform/graphics/android/GLUtils.cpp
index 2200d05..e30e7c1 100644
--- a/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/WebCore/platform/graphics/android/GLUtils.cpp
@@ -311,7 +311,11 @@ void GLUtils::createTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint fi
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, bitmap.width(), bitmap.height(),
0, internalformat, type, bitmap.getPixels());
bitmap.unlockPixels();
- GLUtils::checkGlError("glTexImage2D");
+ if (GLUtils::checkGlError("glTexImage2D")) {
+ XLOG("GL ERROR: glTexImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
+ " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
+ bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
+ }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
}
@@ -328,7 +332,11 @@ void GLUtils::updateTextureWithBitmap(GLuint texture, SkBitmap& bitmap, GLint fi
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
internalformat, type, bitmap.getPixels());
bitmap.unlockPixels();
- GLUtils::checkGlError("glTexSubImage2D");
+ if (GLUtils::checkGlError("glTexSubImage2D")) {
+ XLOG("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
+ " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
+ bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
+ }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
}
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index 91e38e5..94e16da 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -486,22 +486,19 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
localMatrix.translate3d(originX + position.x(),
originY + position.y(),
anchorPointZ());
- FloatPoint p(0, 0);
- p = localMatrix.mapPoint(p);
- p = m_transform.mapPoint(p);
-
localMatrix.multLeft(m_transform);
localMatrix.translate3d(-originX,
-originY,
-anchorPointZ());
- p = localMatrix.mapPoint(p);
setDrawTransform(localMatrix);
opacity *= getOpacity();
setDrawOpacity(opacity);
if (m_haveClip) {
- FloatRect clip = (FloatRect) bounds();
+ //The clipping rect calculation and intersetion will be done in Screen Coord now.
+ FloatRect clip =
+ TilesManager::instance()->shader()->clipRectInScreenCoord(drawTransform(), layerSize);
clip.intersect(clipping);
setDrawClip(clip);
} else {
@@ -620,7 +617,7 @@ bool LayerAndroid::drawGL(SkMatrix& matrix)
SkRect rect;
rect.set(0, 0, getSize().width(), getSize().height());
- TilesManager::instance()->shader()->clip(drawTransform(), m_clippingRect);
+ TilesManager::instance()->shader()->clip(m_clippingRect);
if (prepareContext() && m_texture) {
TextureInfo* textureInfo = m_texture->consumerLock();
diff --git a/WebCore/platform/graphics/android/ShaderProgram.cpp b/WebCore/platform/graphics/android/ShaderProgram.cpp
index 15f120d..f61186a 100644
--- a/WebCore/platform/graphics/android/ShaderProgram.cpp
+++ b/WebCore/platform/graphics/android/ShaderProgram.cpp
@@ -56,7 +56,7 @@ static const char gFragmentShader[] =
"uniform sampler2D s_texture; \n"
"void main() {\n"
" gl_FragColor = texture2D(s_texture, v_texCoord); \n"
- " gl_FragColor.a *= alpha; "
+ " gl_FragColor *= alpha; "
"}\n";
GLuint ShaderProgram::loadShader(GLenum shaderType, const char* pSource)
@@ -206,23 +206,29 @@ void ShaderProgram::setViewRect(const IntRect& viewRect)
m_clippingMatrix.multiply(scale);
}
-void ShaderProgram::clip(const TransformationMatrix& drawMatrix,
- const FloatRect& rect)
+// This function transform a clip rect extracted from the current layer
+// into a clip rect in screen coordinates
+FloatRect ShaderProgram::clipRectInScreenCoord(const TransformationMatrix& drawMatrix,
+ const IntSize& size)
{
- if (rect == m_clipRect)
- return;
-
- FloatRect srect(0, 0, rect.width(), rect.height());
+ FloatRect srect(0, 0, size.width(), size.height());
TransformationMatrix renderMatrix = drawMatrix;
renderMatrix.multiply(m_clippingMatrix);
- FloatRect clip = renderMatrix.mapRect(srect);
+ return renderMatrix.mapRect(srect);
+}
+
+// clip is in screen coordinates
+void ShaderProgram::clip(const FloatRect& clip)
+{
+ if (clip == m_clipRect)
+ return;
// we should only call glScissor in this function, so that we can easily
// track the current clipping rect.
glScissor(m_viewRect.x() + clip.x(), m_viewRect.y() + clip.y(),
clip.width(), clip.height());
- m_clipRect = rect;
+ m_clipRect = clip;
}
void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
diff --git a/WebCore/platform/graphics/android/ShaderProgram.h b/WebCore/platform/graphics/android/ShaderProgram.h
index 719a9ac..6508fdb 100644
--- a/WebCore/platform/graphics/android/ShaderProgram.h
+++ b/WebCore/platform/graphics/android/ShaderProgram.h
@@ -41,7 +41,9 @@ class ShaderProgram {
void drawLayerQuad(const TransformationMatrix& drawMatrix,
SkRect& geometry, int textureId, float opacity);
void setViewRect(const IntRect& viewRect);
- void clip(const TransformationMatrix& drawMatrix, const FloatRect& rect);
+ FloatRect clipRectInScreenCoord(const TransformationMatrix& drawMatrix,
+ const IntSize& size);
+ void clip(const FloatRect& rect);
private:
GLuint loadShader(GLenum shaderType, const char* pSource);
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 1f4feaf..fab5d7b 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -383,6 +383,7 @@ void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect)
void LayerChromium::setNeedsDisplay()
{
+ m_dirtyRect.setLocation(FloatPoint());
m_dirtyRect.setSize(m_bounds);
m_contentsDirty = true;
setNeedsCommit();
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index fee64ca..ae2653a 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -143,9 +143,7 @@ static ResamplingMode computeResamplingMode(PlatformContextSkia* platformContext
// Everything else gets resampled.
// If the platform context permits high quality interpolation, use it.
- // High quality interpolation only enabled for scaling and translation.
- if (platformContext->interpolationQuality() == InterpolationHigh
- && !(platformContext->canvas()->getTotalMatrix().getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)))
+ if (platformContext->interpolationQuality() == InterpolationHigh)
return RESAMPLE_AWESOME;
return RESAMPLE_LINEAR;
@@ -180,17 +178,9 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
SkIRect resizedImageRect = // Represents the size of the resized image.
{ 0, 0, destRectRounded.width(), destRectRounded.height() };
- // Apply forward transform to destRect to estimate required size of
- // re-sampled bitmap, and use only in calls required to resize, or that
- // check for the required size.
- SkRect destRectTransformed;
- canvas.getTotalMatrix().mapRect(&destRectTransformed, destRect);
- SkIRect destRectTransformedRounded;
- destRectTransformed.round(&destRectTransformedRounded);
-
- if (srcIsFull && bitmap.hasResizedBitmap(destRectTransformedRounded.width(), destRectTransformedRounded.height())) {
+ if (srcIsFull && bitmap.hasResizedBitmap(destRectRounded.width(), destRectRounded.height())) {
// Yay, this bitmap frame already has a resized version.
- SkBitmap resampled = bitmap.resizedBitmap(destRectTransformedRounded.width(), destRectTransformedRounded.height());
+ SkBitmap resampled = bitmap.resizedBitmap(destRectRounded.width(), destRectRounded.height());
canvas.drawBitmapRect(resampled, 0, destRect, &paint);
return;
}
@@ -217,8 +207,8 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
destBitmapSubsetSkI.height())) {
// We're supposed to resize the entire image and cache it, even though
// we don't need all of it.
- SkBitmap resampled = bitmap.resizedBitmap(destRectTransformedRounded.width(),
- destRectTransformedRounded.height());
+ SkBitmap resampled = bitmap.resizedBitmap(destRectRounded.width(),
+ destRectRounded.height());
canvas.drawBitmapRect(resampled, 0, destRect, &paint);
} else {
// We should only resize the exposed part of the bitmap to do the
@@ -227,7 +217,7 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
// Resample the needed part of the image.
SkBitmap resampled = skia::ImageOperations::Resize(subset,
skia::ImageOperations::RESIZE_LANCZOS3,
- destRectTransformedRounded.width(), destRectTransformedRounded.height(),
+ destRectRounded.width(), destRectRounded.height(),
destBitmapSubsetSkI);
// Compute where the new bitmap should be drawn. Since our new bitmap
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h
index dde8550..ceb8f9b 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/ImageDecoder.h
@@ -326,6 +326,8 @@ namespace WebCore {
// transparency.
virtual bool supportsAlpha() const { return true; }
+ void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
+
// Whether or not the gamma and color profile are applied.
bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index ff1262e..a2b9f8e 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -208,8 +208,13 @@ public:
// Let libjpeg take care of gray->RGB and YCbCr->RGB conversions.
switch (m_info.jpeg_color_space) {
case JCS_GRAYSCALE:
- case JCS_RGB:
case JCS_YCbCr:
+ // Grayscale images get "upsampled" by libjpeg. If we use
+ // their color profile, CoreGraphics will "upsample" them
+ // again, resulting in horizontal distortions.
+ m_decoder->setIgnoreGammaAndColorProfile(true);
+ // Note fall-through!
+ case JCS_RGB:
m_info.out_color_space = JCS_RGB;
break;
case JCS_CMYK:
diff --git a/WebCore/platform/mac/ScrollViewMac.mm b/WebCore/platform/mac/ScrollViewMac.mm
index 7ef5dc4..7e415da 100644
--- a/WebCore/platform/mac/ScrollViewMac.mm
+++ b/WebCore/platform/mac/ScrollViewMac.mm
@@ -147,7 +147,7 @@ void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress)
void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- NSPoint tempPoint = { max(0, scrollPoint.x()), max(0, scrollPoint.y()) }; // Don't use NSMakePoint to work around 4213314.
+ NSPoint tempPoint = { max(-[scrollView() scrollOriginX], scrollPoint.x()), max(0, scrollPoint.y()) }; // Don't use NSMakePoint to work around 4213314.
[documentView() scrollPoint:tempPoint];
END_BLOCK_OBJC_EXCEPTIONS;
}
@@ -202,4 +202,11 @@ bool ScrollView::platformIsOffscreen() const
return ![platformWidget() window] || ![[platformWidget() window] isVisible];
}
+void ScrollView::platformSetScrollOriginX(int x)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ [scrollView() setScrollOriginX:x];
+ END_BLOCK_OBJC_EXCEPTIONS;
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 406a375..b20b41a 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -225,9 +225,13 @@ void FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncod
// We have to include the filename=".." part in the header, even if the filename is empty
FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);
- // Add the content type if it is available.
- if (!value.blob()->type().isEmpty())
- FormDataBuilder::addContentTypeToMultiPartHeader(header, value.blob()->type().latin1());
+ // Add the content type if available, or "application/octet-stream" otherwise (RFC 1867).
+ String contentType;
+ if (value.blob()->type().isEmpty())
+ contentType = "application/octet-stream";
+ else
+ contentType = value.blob()->type();
+ FormDataBuilder::addContentTypeToMultiPartHeader(header, contentType.latin1());
}
FormDataBuilder::finishMultiPartHeader(header);