[BlackBerry] New files for BlackBerry::Platform::Graphics::GraphicsContext integration
authoranilsson@rim.com <anilsson@rim.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 11:09:59 +0000 (11:09 +0000)
committeranilsson@rim.com <anilsson@rim.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 11:09:59 +0000 (11:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=111153

Reviewed by Rob Buis.

BlackBerry PR 293208

This patch contains contributions from many members of the BlackBerry
WebKit team:

Rob Buis
Robin Cao
Eli Fidler
Mike Lattanzio
Yong Li
Maxim Mogilnitsky
Joshua Netterfield
Arvid Nilsson
Jakob Petsovits
Konrad Piascik
Jeff Rogers
Artem Simonov
Filip Spacek
George Staikos

Covered by existing tests.

* platform/graphics/blackberry/FontBlackBerry.cpp: Added.
(FSFixedToFloat):
(FloatToFSFixed):
(WebCore):
(WebCore::Font::drawComplexText):
(WebCore::Font::floatWidthForComplexText):
(WebCore::Font::offsetForPositionForComplexText):
(WebCore::Font::selectionRectForComplexText):
(WebCore::Font::drawGlyphs):
(WebCore::Font::canReturnFallbackFontsForComplexText):
(WebCore::Font::drawEmphasisMarksForComplexText):
(WebCore::Font::canExpandAroundIdeographsInComplexText):
* platform/graphics/blackberry/FontCacheBlackBerry.cpp: Added.
(WebCore):
(WebCore::FontCache::platformInit):
(WebCore::FontCache::getFontDataForCharacters):
(WebCore::FontCache::getSimilarFontPlatformData):
(WebCore::FontCache::getLastResortFallbackFont):
(WebCore::FontCache::getTraitsInFamily):
(WebCore::getFamilyNameStringFromFontDescriptionAndFamily):
(WebCore::fontWeightToFontconfigWeight):
(WebCore::FontCache::createFontPlatformData):
* platform/graphics/blackberry/FontCustomPlatformData.h: Added.
(WebCore):
(FontCustomPlatformData):
* platform/graphics/blackberry/FontCustomPlatformDataBlackBerry.cpp: Added.
(WebCore):
(WebCore::FontCustomPlatformData::FontCustomPlatformData):
(WebCore::FontCustomPlatformData::~FontCustomPlatformData):
(WebCore::FontCustomPlatformData::fontPlatformData):
(WebCore::FontCustomPlatformData::supportsFormat):
(WebCore::createFontCustomPlatformData):
* platform/graphics/blackberry/FontPlatformDataBlackBerry.cpp: Added.
(WebCore):
(WebCore::FontPlatformData::FontPlatformData):
(WebCore::FontPlatformData::~FontPlatformData):
(WebCore::FontPlatformData::name):
(WebCore::FontPlatformData::applyState):
(WebCore::FontPlatformData::platformDataInit):
(WebCore::FontPlatformData::platformDataAssign):
(WebCore::FontPlatformData::platformIsEqual):
(WebCore::FontPlatformData::description):
(WebCore::FontPlatformData::harfbuzzFace):
(WebCore::FontPlatformData::scaledFont):
(WebCore::FontPlatformData::setFakeBold):
(WebCore::FontPlatformData::setFakeItalic):
(WebCore::FontPlatformData::platformFontHandle):
(WebCore::FontPlatformData::isFixedPitch):
* platform/graphics/blackberry/GlyphPageTreeNodeBlackBerry.cpp: Added.
(WebCore):
(WorldTypeScopedPtr):
(WebCore::WorldTypeScopedPtr::WorldTypeScopedPtr):
(WebCore::WorldTypeScopedPtr::~WorldTypeScopedPtr):
(WebCore::WorldTypeScopedPtr::get):
(WebCore::GlyphPage::fill):
* platform/graphics/blackberry/GradientBlackBerry.cpp: Added.
(WebCore):
(WebCore::totalStopsNeeded):
(WebCore::fillStops):
(WebCore::Gradient::platformGradient):
(WebCore::Gradient::platformDestroy):
(WebCore::Gradient::fill):
(WebCore::Gradient::setPlatformGradientSpaceTransform):
* platform/graphics/blackberry/GraphicsContextBlackBerry.cpp: Added.
(WebCore):
(GraphicsContextPlatformPrivate):
(WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
(WebCore::GraphicsContext::platformInit):
(WebCore::GraphicsContext::platformDestroy):
(WebCore::GraphicsContext::platformContext):
(WebCore::GraphicsContext::savePlatformState):
(WebCore::GraphicsContext::restorePlatformState):
(WebCore::GraphicsContext::setIsAcceleratedContext):
(WebCore::GraphicsContext::isAcceleratedContext):
(WebCore::GraphicsContext::getCTM):
(WebCore::GraphicsContext::concatCTM):
(WebCore::GraphicsContext::setCTM):
(WebCore::GraphicsContext::scale):
(WebCore::GraphicsContext::rotate):
(WebCore::GraphicsContext::translate):
(WebCore::GraphicsContext::drawEllipse):
(WebCore::GraphicsContext::strokeArc):
(WebCore::GraphicsContext::drawConvexPolygon):
(WebCore::GraphicsContext::drawRect):
(WebCore::GraphicsContext::fillRect):
(WebCore::GraphicsContext::clearRect):
(WebCore::GraphicsContext::strokeRect):
(WebCore::GraphicsContext::fillRoundedRect):
(WebCore::GraphicsContext::roundToDevicePixels):
(WebCore::GraphicsContext::setPlatformShadow):
(WebCore::GraphicsContext::clearPlatformShadow):
(WebCore::GraphicsContext::beginPlatformTransparencyLayer):
(WebCore::GraphicsContext::endPlatformTransparencyLayer):
(WebCore::GraphicsContext::supportsTransparencyLayers):
(WebCore::GraphicsContext::setLineCap):
(WebCore::GraphicsContext::setLineDash):
(WebCore::GraphicsContext::setLineJoin):
(WebCore::GraphicsContext::setMiterLimit):
(WebCore::GraphicsContext::setAlpha):
(WebCore::GraphicsContext::clip):
(WebCore::GraphicsContext::clipOut):
(WebCore::GraphicsContext::clipConvexPolygon):
(WebCore::GraphicsContext::addRoundedRectClip):
(WebCore::GraphicsContext::clipOutRoundedRect):
(WebCore::GraphicsContext::clipBounds):
(WebCore::GraphicsContext::addInnerRoundedRectClip):
(WebCore::GraphicsContext::setURLForRect):
(WebCore::GraphicsContext::setPlatformTextDrawingMode):
(WebCore::GraphicsContext::setPlatformStrokeColor):
(WebCore::GraphicsContext::setPlatformStrokeStyle):
(WebCore::GraphicsContext::setPlatformStrokeThickness):
(WebCore::GraphicsContext::setPlatformFillColor):
(WebCore::GraphicsContext::setPlatformCompositeOperation):
(WebCore::GraphicsContext::setPlatformShouldAntialias):
(WebCore::GraphicsContext::setImageInterpolationQuality):
(WebCore::GraphicsContext::imageInterpolationQuality):
* platform/graphics/blackberry/ITypeUtils.h: Added.
(floatToITypeFixed):
(intToITypeFixed):
(iTypeFixedToFloat):
* platform/graphics/blackberry/ImageBufferBlackBerry.cpp: Added.
(WebCore):
(WebCore::makeBufferCurrent):
(WebCore::getImageDataInternal):
(WebCore::ImageBufferData::getImageData):
(WebCore::flushAndDraw):
(WebCore::ImageBufferData::draw):
(WebCore::ImageBuffer::ImageBuffer):
(WebCore::ImageBuffer::~ImageBuffer):
(WebCore::ImageBuffer::context):
(WebCore::ImageBuffer::platformLayer):
(WebCore::ImageBuffer::copyImage):
(WebCore::ImageBuffer::clip):
(WebCore::ImageBuffer::draw):
(WebCore::ImageBuffer::drawPattern):
(WebCore::ImageBuffer::platformTransformColorSpace):
(WebCore::ImageBuffer::getUnmultipliedImageData):
(WebCore::ImageBuffer::getPremultipliedImageData):
(WebCore::ImageBuffer::putByteArray):
(WebCore::ImageBuffer::toDataURL):
* platform/graphics/blackberry/ImageBufferDataBlackBerry.h: Added.
(WebCore):
(ImageBufferData):
* platform/graphics/blackberry/PathBlackBerry.cpp: Added.
(WebCore):
(WebCore::scratchContext):
(WebCore::Path::Path):
(WebCore::Path::~Path):
(WebCore::Path::operator=):
(WebCore::Path::currentPoint):
(WebCore::Path::contains):
(WebCore::Path::strokeContains):
(WebCore::Path::translate):
(WebCore::Path::boundingRect):
(WebCore::Path::strokeBoundingRect):
(WebCore::Path::moveTo):
(WebCore::Path::addLineTo):
(WebCore::Path::addQuadCurveTo):
(WebCore::Path::addBezierCurveTo):
(WebCore::Path::addArcTo):
(WebCore::Path::closeSubpath):
(WebCore::Path::addArc):
(WebCore::Path::addRect):
(WebCore::Path::addEllipse):
(WebCore::Path::platformAddPathForRoundedRect):
(WebCore::Path::clear):
(WebCore::Path::isEmpty):
(WebCore::Path::hasCurrentPoint):
(WebCore::Path::apply):
(WebCore::Path::transform):
(WebCore::GraphicsContext::fillPath):
(WebCore::GraphicsContext::strokePath):
(WebCore::GraphicsContext::drawFocusRing):
(WebCore::GraphicsContext::drawLine):
(WebCore::GraphicsContext::drawLineForDocumentMarker):
(WebCore::GraphicsContext::drawLineForText):
(WebCore::GraphicsContext::clip):
(WebCore::GraphicsContext::clipPath):
(WebCore::GraphicsContext::canvasClip):
(WebCore::GraphicsContext::clipOut):
* platform/graphics/blackberry/PatternBlackBerry.cpp: Added.
(WebCore):
(WebCore::Pattern::platformDestroy):
(WebCore::Pattern::platformPattern):
(WebCore::Pattern::setPlatformPatternSpaceTransform):
* platform/graphics/blackberry/PlatformSupport.cpp: Added.
(WebCore):
(WebCore::PlatformSupport::getFontFamilyForCharacters):
* platform/graphics/blackberry/PlatformSupport.h: Added.
(WebCore):
(PlatformSupport):
(FontFamily):
* platform/graphics/blackberry/SimpleFontDataBlackBerry.cpp: Added.
(WebCore):
(WebCore::FSFixedToFloat):
(WebCore::SimpleFontData::platformInit):
(WebCore::SimpleFontData::platformCharWidthInit):
(WebCore::SimpleFontData::platformDestroy):
(WebCore::SimpleFontData::createScaledFontData):
(WebCore::SimpleFontData::smallCapsFontData):
(WebCore::SimpleFontData::emphasisMarkFontData):
(WebCore::SimpleFontData::containsCharacters):
(WebCore::SimpleFontData::determinePitch):
(WebCore::SimpleFontData::platformBoundsForGlyph):
(WebCore::SimpleFontData::platformWidthForGlyph):
(WebCore::SimpleFontData::canRenderCombiningCharacterSequence):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@144612 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/blackberry/FontBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/FontCacheBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/FontCustomPlatformData.h [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/FontCustomPlatformDataBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/FontPlatformDataBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/GlyphPageTreeNodeBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/GradientBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/GraphicsContextBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/ITypeUtils.h [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/ImageBufferBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/ImageBufferDataBlackBerry.h [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/PathBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/PatternBlackBerry.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/PlatformSupport.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/PlatformSupport.h [new file with mode: 0644]
Source/WebCore/platform/graphics/blackberry/SimpleFontDataBlackBerry.cpp [new file with mode: 0644]

index cf4ba8c..53c6a22 100644 (file)
@@ -1,3 +1,239 @@
+2013-03-04  Arvid Nilsson  <anilsson@rim.com>
+
+        [BlackBerry] New files for BlackBerry::Platform::Graphics::GraphicsContext integration
+        https://bugs.webkit.org/show_bug.cgi?id=111153
+
+        Reviewed by Rob Buis.
+
+        BlackBerry PR 293208
+
+        This patch contains contributions from many members of the BlackBerry
+        WebKit team:
+
+        Rob Buis
+        Robin Cao
+        Eli Fidler
+        Mike Lattanzio
+        Yong Li
+        Maxim Mogilnitsky
+        Joshua Netterfield
+        Arvid Nilsson
+        Jakob Petsovits
+        Konrad Piascik
+        Jeff Rogers
+        Artem Simonov
+        Filip Spacek
+        George Staikos
+
+        Covered by existing tests.
+
+        * platform/graphics/blackberry/FontBlackBerry.cpp: Added.
+        (FSFixedToFloat):
+        (FloatToFSFixed):
+        (WebCore):
+        (WebCore::Font::drawComplexText):
+        (WebCore::Font::floatWidthForComplexText):
+        (WebCore::Font::offsetForPositionForComplexText):
+        (WebCore::Font::selectionRectForComplexText):
+        (WebCore::Font::drawGlyphs):
+        (WebCore::Font::canReturnFallbackFontsForComplexText):
+        (WebCore::Font::drawEmphasisMarksForComplexText):
+        (WebCore::Font::canExpandAroundIdeographsInComplexText):
+        * platform/graphics/blackberry/FontCacheBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::FontCache::platformInit):
+        (WebCore::FontCache::getFontDataForCharacters):
+        (WebCore::FontCache::getSimilarFontPlatformData):
+        (WebCore::FontCache::getLastResortFallbackFont):
+        (WebCore::FontCache::getTraitsInFamily):
+        (WebCore::getFamilyNameStringFromFontDescriptionAndFamily):
+        (WebCore::fontWeightToFontconfigWeight):
+        (WebCore::FontCache::createFontPlatformData):
+        * platform/graphics/blackberry/FontCustomPlatformData.h: Added.
+        (WebCore):
+        (FontCustomPlatformData):
+        * platform/graphics/blackberry/FontCustomPlatformDataBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::FontCustomPlatformData::FontCustomPlatformData):
+        (WebCore::FontCustomPlatformData::~FontCustomPlatformData):
+        (WebCore::FontCustomPlatformData::fontPlatformData):
+        (WebCore::FontCustomPlatformData::supportsFormat):
+        (WebCore::createFontCustomPlatformData):
+        * platform/graphics/blackberry/FontPlatformDataBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::FontPlatformData::FontPlatformData):
+        (WebCore::FontPlatformData::~FontPlatformData):
+        (WebCore::FontPlatformData::name):
+        (WebCore::FontPlatformData::applyState):
+        (WebCore::FontPlatformData::platformDataInit):
+        (WebCore::FontPlatformData::platformDataAssign):
+        (WebCore::FontPlatformData::platformIsEqual):
+        (WebCore::FontPlatformData::description):
+        (WebCore::FontPlatformData::harfbuzzFace):
+        (WebCore::FontPlatformData::scaledFont):
+        (WebCore::FontPlatformData::setFakeBold):
+        (WebCore::FontPlatformData::setFakeItalic):
+        (WebCore::FontPlatformData::platformFontHandle):
+        (WebCore::FontPlatformData::isFixedPitch):
+        * platform/graphics/blackberry/GlyphPageTreeNodeBlackBerry.cpp: Added.
+        (WebCore):
+        (WorldTypeScopedPtr):
+        (WebCore::WorldTypeScopedPtr::WorldTypeScopedPtr):
+        (WebCore::WorldTypeScopedPtr::~WorldTypeScopedPtr):
+        (WebCore::WorldTypeScopedPtr::get):
+        (WebCore::GlyphPage::fill):
+        * platform/graphics/blackberry/GradientBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::totalStopsNeeded):
+        (WebCore::fillStops):
+        (WebCore::Gradient::platformGradient):
+        (WebCore::Gradient::platformDestroy):
+        (WebCore::Gradient::fill):
+        (WebCore::Gradient::setPlatformGradientSpaceTransform):
+        * platform/graphics/blackberry/GraphicsContextBlackBerry.cpp: Added.
+        (WebCore):
+        (GraphicsContextPlatformPrivate):
+        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
+        (WebCore::GraphicsContext::platformInit):
+        (WebCore::GraphicsContext::platformDestroy):
+        (WebCore::GraphicsContext::platformContext):
+        (WebCore::GraphicsContext::savePlatformState):
+        (WebCore::GraphicsContext::restorePlatformState):
+        (WebCore::GraphicsContext::setIsAcceleratedContext):
+        (WebCore::GraphicsContext::isAcceleratedContext):
+        (WebCore::GraphicsContext::getCTM):
+        (WebCore::GraphicsContext::concatCTM):
+        (WebCore::GraphicsContext::setCTM):
+        (WebCore::GraphicsContext::scale):
+        (WebCore::GraphicsContext::rotate):
+        (WebCore::GraphicsContext::translate):
+        (WebCore::GraphicsContext::drawEllipse):
+        (WebCore::GraphicsContext::strokeArc):
+        (WebCore::GraphicsContext::drawConvexPolygon):
+        (WebCore::GraphicsContext::drawRect):
+        (WebCore::GraphicsContext::fillRect):
+        (WebCore::GraphicsContext::clearRect):
+        (WebCore::GraphicsContext::strokeRect):
+        (WebCore::GraphicsContext::fillRoundedRect):
+        (WebCore::GraphicsContext::roundToDevicePixels):
+        (WebCore::GraphicsContext::setPlatformShadow):
+        (WebCore::GraphicsContext::clearPlatformShadow):
+        (WebCore::GraphicsContext::beginPlatformTransparencyLayer):
+        (WebCore::GraphicsContext::endPlatformTransparencyLayer):
+        (WebCore::GraphicsContext::supportsTransparencyLayers):
+        (WebCore::GraphicsContext::setLineCap):
+        (WebCore::GraphicsContext::setLineDash):
+        (WebCore::GraphicsContext::setLineJoin):
+        (WebCore::GraphicsContext::setMiterLimit):
+        (WebCore::GraphicsContext::setAlpha):
+        (WebCore::GraphicsContext::clip):
+        (WebCore::GraphicsContext::clipOut):
+        (WebCore::GraphicsContext::clipConvexPolygon):
+        (WebCore::GraphicsContext::addRoundedRectClip):
+        (WebCore::GraphicsContext::clipOutRoundedRect):
+        (WebCore::GraphicsContext::clipBounds):
+        (WebCore::GraphicsContext::addInnerRoundedRectClip):
+        (WebCore::GraphicsContext::setURLForRect):
+        (WebCore::GraphicsContext::setPlatformTextDrawingMode):
+        (WebCore::GraphicsContext::setPlatformStrokeColor):
+        (WebCore::GraphicsContext::setPlatformStrokeStyle):
+        (WebCore::GraphicsContext::setPlatformStrokeThickness):
+        (WebCore::GraphicsContext::setPlatformFillColor):
+        (WebCore::GraphicsContext::setPlatformCompositeOperation):
+        (WebCore::GraphicsContext::setPlatformShouldAntialias):
+        (WebCore::GraphicsContext::setImageInterpolationQuality):
+        (WebCore::GraphicsContext::imageInterpolationQuality):
+        * platform/graphics/blackberry/ITypeUtils.h: Added.
+        (floatToITypeFixed):
+        (intToITypeFixed):
+        (iTypeFixedToFloat):
+        * platform/graphics/blackberry/ImageBufferBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::makeBufferCurrent):
+        (WebCore::getImageDataInternal):
+        (WebCore::ImageBufferData::getImageData):
+        (WebCore::flushAndDraw):
+        (WebCore::ImageBufferData::draw):
+        (WebCore::ImageBuffer::ImageBuffer):
+        (WebCore::ImageBuffer::~ImageBuffer):
+        (WebCore::ImageBuffer::context):
+        (WebCore::ImageBuffer::platformLayer):
+        (WebCore::ImageBuffer::copyImage):
+        (WebCore::ImageBuffer::clip):
+        (WebCore::ImageBuffer::draw):
+        (WebCore::ImageBuffer::drawPattern):
+        (WebCore::ImageBuffer::platformTransformColorSpace):
+        (WebCore::ImageBuffer::getUnmultipliedImageData):
+        (WebCore::ImageBuffer::getPremultipliedImageData):
+        (WebCore::ImageBuffer::putByteArray):
+        (WebCore::ImageBuffer::toDataURL):
+        * platform/graphics/blackberry/ImageBufferDataBlackBerry.h: Added.
+        (WebCore):
+        (ImageBufferData):
+        * platform/graphics/blackberry/PathBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::scratchContext):
+        (WebCore::Path::Path):
+        (WebCore::Path::~Path):
+        (WebCore::Path::operator=):
+        (WebCore::Path::currentPoint):
+        (WebCore::Path::contains):
+        (WebCore::Path::strokeContains):
+        (WebCore::Path::translate):
+        (WebCore::Path::boundingRect):
+        (WebCore::Path::strokeBoundingRect):
+        (WebCore::Path::moveTo):
+        (WebCore::Path::addLineTo):
+        (WebCore::Path::addQuadCurveTo):
+        (WebCore::Path::addBezierCurveTo):
+        (WebCore::Path::addArcTo):
+        (WebCore::Path::closeSubpath):
+        (WebCore::Path::addArc):
+        (WebCore::Path::addRect):
+        (WebCore::Path::addEllipse):
+        (WebCore::Path::platformAddPathForRoundedRect):
+        (WebCore::Path::clear):
+        (WebCore::Path::isEmpty):
+        (WebCore::Path::hasCurrentPoint):
+        (WebCore::Path::apply):
+        (WebCore::Path::transform):
+        (WebCore::GraphicsContext::fillPath):
+        (WebCore::GraphicsContext::strokePath):
+        (WebCore::GraphicsContext::drawFocusRing):
+        (WebCore::GraphicsContext::drawLine):
+        (WebCore::GraphicsContext::drawLineForDocumentMarker):
+        (WebCore::GraphicsContext::drawLineForText):
+        (WebCore::GraphicsContext::clip):
+        (WebCore::GraphicsContext::clipPath):
+        (WebCore::GraphicsContext::canvasClip):
+        (WebCore::GraphicsContext::clipOut):
+        * platform/graphics/blackberry/PatternBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::Pattern::platformDestroy):
+        (WebCore::Pattern::platformPattern):
+        (WebCore::Pattern::setPlatformPatternSpaceTransform):
+        * platform/graphics/blackberry/PlatformSupport.cpp: Added.
+        (WebCore):
+        (WebCore::PlatformSupport::getFontFamilyForCharacters):
+        * platform/graphics/blackberry/PlatformSupport.h: Added.
+        (WebCore):
+        (PlatformSupport):
+        (FontFamily):
+        * platform/graphics/blackberry/SimpleFontDataBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::FSFixedToFloat):
+        (WebCore::SimpleFontData::platformInit):
+        (WebCore::SimpleFontData::platformCharWidthInit):
+        (WebCore::SimpleFontData::platformDestroy):
+        (WebCore::SimpleFontData::createScaledFontData):
+        (WebCore::SimpleFontData::smallCapsFontData):
+        (WebCore::SimpleFontData::emphasisMarkFontData):
+        (WebCore::SimpleFontData::containsCharacters):
+        (WebCore::SimpleFontData::determinePitch):
+        (WebCore::SimpleFontData::platformBoundsForGlyph):
+        (WebCore::SimpleFontData::platformWidthForGlyph):
+        (WebCore::SimpleFontData::canRenderCombiningCharacterSequence):
+
 2013-03-04  Adam Bergkvist  <adam.bergkvist@ericsson.com>
 
         MediaStream API: local addTrack() and removeTrack() operations should not fire events.
diff --git a/Source/WebCore/platform/graphics/blackberry/FontBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/FontBlackBerry.cpp
new file mode 100644 (file)
index 0000000..f067a40
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2012, 2013 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "config.h"
+#include "Font.h"
+
+#include "AffineTransform.h"
+#include "FloatPoint.h"
+#include "FloatRect.h"
+#include "FontCache.h"
+#include "GlyphBuffer.h"
+#include "GraphicsContext.h"
+#include "HarfBuzzShaper.h"
+#include "ShadowBlur.h"
+#include "TextRun.h"
+
+#include <BlackBerryPlatformGraphicsContext.h>
+
+#include <fs_api.h>
+#include <wtf/MathExtras.h>
+
+static inline float FSFixedToFloat(FS_FIXED n) { return n / 65536.0; }
+static inline FS_FIXED FloatToFSFixed(float n) { return static_cast<FS_FIXED>(n * 65536); }
+
+namespace WebCore {
+
+void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+{
+    if (!run.length())
+        return;
+
+    GlyphBuffer glyphBuffer;
+    HarfBuzzShaper shaper(this, run);
+    shaper.setDrawRange(from, to);
+    if (!shaper.shape(&glyphBuffer))
+        return;
+    FloatPoint adjustedPoint = shaper.adjustStartPoint(point);
+
+    drawGlyphBuffer(context, run, glyphBuffer, adjustedPoint);
+}
+
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* /* glyphOverflow */) const
+{
+    HarfBuzzShaper shaper(this, run);
+    if (!shaper.shape())
+        return 0;
+    return shaper.totalWidth();
+}
+
+// Return the code point index for the given |x| offset into the text run.
+int Font::offsetForPositionForComplexText(const TextRun& run, float position, bool includePartialGlyphs) const
+{
+    // FIXME: This truncation is not a problem for HTML, but only affects SVG, which passes floating-point numbers
+    // to Font::offsetForPosition(). Bug http://webkit.org/b/40673 tracks fixing this problem.
+    int targetX = static_cast<int>(position);
+
+    HarfBuzzShaper shaper(this, run);
+    if (!shaper.shape())
+        return 0;
+    return shaper.offsetForPosition(targetX);
+}
+
+FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int height, int from, int to) const
+{
+    HarfBuzzShaper shaper(this, run);
+    if (!shaper.shape())
+        return FloatRect();
+    return shaper.selectionRect(point, height, from, to);
+}
+
+void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
+{
+    FS_STATE* iType = font->platformData().scaledFont(context->getCTM().yScale());
+    if (!iType)
+        return;
+
+    FloatPoint adjustedPoint = point;
+
+    if (font->platformData().orientation() == Vertical)
+        adjustedPoint.move(-(font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent()), 0);
+
+    bool softwareBlurRequired = context->state().shadowBlur / font->fontMetrics().xHeight() > 0.5;
+
+    FloatSize currentShadowOffset;
+    float currentShadowBlur;
+    Color currentShadowColor;
+    ColorSpace currentColorSpace;
+
+    // If we have a shadow blur, and it is too big to apply at text-render time, we must render it now.
+    if (context->hasShadow() && softwareBlurRequired) {
+        context->getShadow(currentShadowOffset, currentShadowBlur, currentShadowColor, currentColorSpace);
+
+        const GraphicsContextState state = context->state();
+        FloatSize offset = state.shadowOffset;
+        if (state.shadowsIgnoreTransforms)
+            offset.setHeight(-offset.height());
+        ShadowBlur shadow(FloatSize(state.shadowBlur, state.shadowBlur), offset, state.shadowColor, state.shadowColorSpace);
+        FloatPoint minPoint(adjustedPoint.x(), adjustedPoint.y() - fontMetrics().ascent());
+        FloatPoint maxPoint(adjustedPoint.x(), adjustedPoint.y() + fontMetrics().descent());
+        FloatPoint currentPoint = adjustedPoint;
+        for (int i = 0; i < numGlyphs; ++i) {
+            currentPoint += *glyphBuffer.advances(from + i);
+            minPoint.setX(std::min(minPoint.x(), currentPoint.x()));
+            minPoint.setY(std::min(minPoint.y(), currentPoint.y()));
+            maxPoint = maxPoint.expandedTo(currentPoint);
+        }
+        const FloatRect boundingRect(minPoint.x(), minPoint.y(), maxPoint.x() - minPoint.x(), maxPoint.y() - minPoint.y());
+        GraphicsContext* shadowContext = shadow.beginShadowLayer(context, boundingRect);
+        if (shadowContext) {
+            iType = font->platformData().scaledFont(shadowContext->getCTM().yScale());
+            shadowContext->platformContext()->addGlyphs(glyphBuffer.glyphs(from),
+                reinterpret_cast<const BlackBerry::Platform::FloatSize*>(glyphBuffer.advances(from)),
+                numGlyphs, adjustedPoint, iType, 0, 0);
+            iType = font->platformData().scaledFont(context->getCTM().yScale());
+            shadow.endShadowLayer(context);
+        }
+        context->platformContext()->clearShadow();
+    }
+
+    context->platformContext()->addGlyphs(glyphBuffer.glyphs(from),
+        reinterpret_cast<const BlackBerry::Platform::FloatSize*>(glyphBuffer.advances(from)),
+        numGlyphs, adjustedPoint, iType,
+        context->fillGradient() ? context->fillGradient()->platformGradient() : (context->fillPattern() ? context->fillPattern()->platformPattern(AffineTransform()) : static_cast<BlackBerry::Platform::Graphics::Paint*>(0)),
+        context->strokeGradient() ? context->strokeGradient()->platformGradient() : (context->strokePattern() ? context->strokePattern()->platformPattern(AffineTransform()) : static_cast<BlackBerry::Platform::Graphics::Paint*>(0)));
+
+    if (softwareBlurRequired)
+        context->platformContext()->setShadow(currentShadowOffset, currentShadowBlur, currentShadowColor.isValid() ? currentShadowColor.rgb() : makeRGBA(0, 0, 0, 0xFF / 3), context->state().shadowsIgnoreTransforms);
+}
+
+bool Font::canReturnFallbackFontsForComplexText()
+{
+    return false;
+}
+
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    // notImplemented();
+}
+
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+    return false;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/blackberry/FontCacheBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/FontCacheBlackBerry.cpp
new file mode 100644 (file)
index 0000000..08d2f11
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2010 Igalia S.L.
+ * Copyright (C) 2012, 2013 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "config.h"
+#include "FontCache.h"
+
+#include "Font.h"
+#include "FontDescription.h"
+#include "FontPlatformData.h"
+#include "ITypeUtils.h"
+#include "Logging.h"
+#include "NotImplemented.h"
+#include "PlatformSupport.h"
+#include "SimpleFontData.h"
+
+#include <BlackBerryPlatformGraphicsContext.h>
+#include <fontconfig/fontconfig.h>
+#include <fs_api.h>
+#include <unicode/locid.h>
+#include <wtf/Assertions.h>
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+void FontCache::platformInit()
+{
+    // It's fine to call FcInit multiple times per the documentation.
+    if (!FcInit())
+        CRASH();
+}
+
+const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+{
+    icu::Locale locale = icu::Locale::getDefault();
+    PlatformSupport::FontFamily family;
+    PlatformSupport::getFontFamilyForCharacters(characters, length, locale.getLanguage(), font.fontDescription(), &family);
+    if (family.name.isEmpty())
+        return 0;
+
+    AtomicString atomicFamily(family.name);
+    // Changes weight and/or italic of given FontDescription depends on
+    // the result of fontconfig so that keeping the correct font mapping
+    // of the given characters. See http://crbug.com/32109 for details.
+    bool shouldSetFakeBold = false;
+    bool shouldSetFakeItalic = false;
+    FontDescription description(font.fontDescription());
+    if (family.isBold && description.weight() < FontWeightBold)
+        description.setWeight(FontWeightBold);
+    if (!family.isBold && description.weight() >= FontWeightBold) {
+        shouldSetFakeBold = true;
+        description.setWeight(FontWeightNormal);
+    }
+    if (family.isItalic && description.italic() == FontItalicOff)
+        description.setItalic(FontItalicOn);
+    if (!family.isItalic && description.italic() == FontItalicOn) {
+        shouldSetFakeItalic = true;
+        description.setItalic(FontItalicOff);
+    }
+
+    FontPlatformData* substitutePlatformData = getCachedFontPlatformData(description, atomicFamily, DoNotRetain);
+    if (!substitutePlatformData)
+        return 0;
+    FontPlatformData platformData = FontPlatformData(*substitutePlatformData);
+    platformData.setFakeBold(shouldSetFakeBold);
+    platformData.setFakeItalic(shouldSetFakeItalic);
+    return getCachedFontData(&platformData, DoNotRetain);
+}
+
+SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+{
+    return 0;
+}
+
+SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain)
+{
+    DEFINE_STATIC_LOCAL(const AtomicString, sansStr, ("Sans"));
+    DEFINE_STATIC_LOCAL(const AtomicString, serifStr, ("Serif"));
+    DEFINE_STATIC_LOCAL(const AtomicString, monospaceStr, ("Monospace"));
+
+    FontPlatformData* fontPlatformData = 0;
+    switch (description.genericFamily()) {
+    case FontDescription::SerifFamily:
+        fontPlatformData = getCachedFontPlatformData(description, serifStr);
+        break;
+    case FontDescription::MonospaceFamily:
+        fontPlatformData = getCachedFontPlatformData(description, monospaceStr);
+        break;
+    case FontDescription::SansSerifFamily:
+    default:
+        fontPlatformData = getCachedFontPlatformData(description, sansStr);
+        break;
+    }
+
+    if (!fontPlatformData) {
+        DEFINE_STATIC_LOCAL(const AtomicString, arialStr, ("Arial"));
+        fontPlatformData = getCachedFontPlatformData(description, arialStr);
+    }
+
+    ASSERT(fontPlatformData);
+    return getCachedFontData(fontPlatformData);
+}
+
+void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
+{
+    notImplemented();
+}
+
+static String getFamilyNameStringFromFontDescriptionAndFamily(const FontDescription& fontDescription, const AtomicString& family)
+{
+    // If we're creating a fallback font (e.g. "-webkit-monospace"), convert the name into
+    // the fallback name (like "monospace") that fontconfig understands.
+    if (family.length() && !family.startsWith("-webkit-"))
+        return family.string();
+
+    switch (fontDescription.genericFamily()) {
+    case FontDescription::StandardFamily:
+    case FontDescription::SerifFamily:
+        return "serif";
+    case FontDescription::SansSerifFamily:
+        return "sans-serif";
+    case FontDescription::MonospaceFamily:
+        return "monospace";
+    case FontDescription::CursiveFamily:
+        return "cursive";
+    case FontDescription::FantasyFamily:
+        return "fantasy";
+    case FontDescription::NoFamily:
+    default:
+        return "";
+    }
+}
+
+int fontWeightToFontconfigWeight(FontWeight weight)
+{
+    switch (weight) {
+    case FontWeight100:
+        return FC_WEIGHT_THIN;
+    case FontWeight200:
+        return FC_WEIGHT_ULTRALIGHT;
+    case FontWeight300:
+        return FC_WEIGHT_LIGHT;
+    case FontWeight400:
+        return FC_WEIGHT_REGULAR;
+    case FontWeight500:
+        return FC_WEIGHT_MEDIUM;
+    case FontWeight600:
+        return FC_WEIGHT_SEMIBOLD;
+    case FontWeight700:
+        return FC_WEIGHT_BOLD;
+    case FontWeight800:
+        return FC_WEIGHT_EXTRABOLD;
+    case FontWeight900:
+        return FC_WEIGHT_ULTRABLACK;
+    default:
+        ASSERT_NOT_REACHED();
+        return FC_WEIGHT_REGULAR;
+    }
+}
+
+FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
+{
+    // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
+    // says that we must find an exact match for font family, slant (italic or oblique can be used)
+    // and font weight (we only match bold/non-bold here).
+    FcPattern* pattern = FcPatternCreate();
+    String familyNameString(getFamilyNameStringFromFontDescriptionAndFamily(fontDescription, family));
+    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data())))
+        return 0;
+
+    bool italic = fontDescription.italic();
+    if (!FcPatternAddInteger(pattern, FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN))
+        return 0;
+    if (!FcPatternAddInteger(pattern, FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight())))
+        return 0;
+    if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontDescription.computedPixelSize()))
+        return 0;
+
+    // The strategy is originally from Skia (src/ports/SkFontHost_fontconfig.cpp):
+
+    // Allow Fontconfig to do pre-match substitution. Unless we are accessing a "fallback"
+    // family like "sans," this is the only time we allow Fontconfig to substitute one
+    // family name for another (i.e. if the fonts are aliased to each other).
+    FcConfigSubstitute(0, pattern, FcMatchPattern);
+    FcDefaultSubstitute(pattern);
+
+    FcChar8* fontConfigFamilyNameAfterConfiguration;
+    FcPatternGetString(pattern, FC_FAMILY, 0, &fontConfigFamilyNameAfterConfiguration);
+    String familyNameAfterConfiguration = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterConfiguration));
+
+    FcResult fontConfigResult;
+    FcPattern* resultPattern = FcFontMatch(0, pattern, &fontConfigResult);
+    FcPatternDestroy(pattern);
+    if (!resultPattern) // No match.
+        return 0;
+
+    FcChar8* fontConfigFamilyNameAfterMatching;
+    FcPatternGetString(resultPattern, FC_FAMILY, 0, &fontConfigFamilyNameAfterMatching);
+    String familyNameAfterMatching = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterMatching));
+
+    // If Fontconfig gave use a different font family than the one we requested, we should ignore it
+    // and allow WebCore to give us the next font on the CSS fallback list. The only exception is if
+    // this family name is a commonly used generic family.
+    if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching)
+        && !(equalIgnoringCase(familyNameString, "sans") || equalIgnoringCase(familyNameString, "sans-serif")
+            || equalIgnoringCase(familyNameString, "serif") || equalIgnoringCase(familyNameString, "monospace")
+            || equalIgnoringCase(familyNameString, "fantasy") || equalIgnoringCase(familyNameString, "cursive")))
+        return 0;
+
+    int fontWeight;
+    FcPatternGetInteger(resultPattern, FC_WEIGHT, 0, &fontWeight);
+    bool shouldFakeBold = fontWeight < FC_WEIGHT_BOLD && fontDescription.weight() >= FontWeightBold;
+
+    int fontSlant;
+    FcPatternGetInteger(resultPattern, FC_SLANT, 0, &fontSlant);
+    bool shouldFakeItalic = fontSlant == FC_SLANT_ROMAN && fontDescription.italic() == FontItalicOn;
+
+    FcChar8* fontFileName;
+    FcPatternGetString(resultPattern, FC_FILE, 0, &fontFileName);
+    // fprintf(stderr, "Looking for %s found %s: i:%d b:%d\n", family.string().latin1().data(), fontFileName, shouldFakeItalic, shouldFakeBold);
+    FcPatternDestroy(resultPattern);
+
+    FILECHAR name[MAX_FONT_NAME_LEN+1];
+    memset(name, 0, MAX_FONT_NAME_LEN+1);
+    // fprintf(stderr, "FS_load_font %s: ", fontFileName);
+    if (FS_load_font(BlackBerry::Platform::Graphics::getIType(), reinterpret_cast<FILECHAR*>(fontFileName), 0, 0, MAX_FONT_NAME_LEN, name) != SUCCESS)
+        return 0;
+    // fprintf(stderr, " %s\n", name);
+
+    return new FontPlatformData(name, fontDescription.computedSize(), shouldFakeBold, shouldFakeItalic, fontDescription.orientation(), fontDescription.textOrientation());
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/blackberry/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/blackberry/FontCustomPlatformData.h
new file mode 100644 (file)
index 0000000..ca2dab0
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef FontCustomPlatformData_h
+#define FontCustomPlatformData_h
+
+#include "FontOrientation.h"
+#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
+#include "TextOrientation.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/text/WTFString.h>
+
+typedef char FILECHAR;
+struct FS_STATE;
+
+namespace WebCore {
+
+class FontPlatformData;
+class MonotypeFont;
+class SharedBuffer;
+
+struct FontCustomPlatformData {
+    WTF_MAKE_NONCOPYABLE(FontCustomPlatformData);
+public:
+    FontCustomPlatformData(FILECHAR* fontName, PassRefPtr<SharedBuffer>);
+    ~FontCustomPlatformData();
+
+    FontPlatformData fontPlatformData(int size, bool syntheticBold, bool syntheticItalic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight,
+        FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+
+    static bool supportsFormat(const String&);
+
+    FILECHAR* m_fontName;
+    RefPtr<SharedBuffer> m_buffer;
+};
+
+FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*);
+
+} // namespace WebCore
+
+#endif // FontCustomPlatformData_h
diff --git a/Source/WebCore/platform/graphics/blackberry/FontCustomPlatformDataBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/FontCustomPlatformDataBlackBerry.cpp
new file mode 100644 (file)
index 0000000..5667d8f
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012, 2013 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "FontCustomPlatformData.h"
+
+#include "FontPlatformData.h"
+#include "ITypeUtils.h"
+#include "OpenTypeSanitizer.h"
+#include "SharedBuffer.h"
+
+#include <BlackBerryPlatformGraphicsContext.h>
+#include <fs_api.h>
+
+namespace WebCore {
+
+FontCustomPlatformData::FontCustomPlatformData(FILECHAR* fontName, PassRefPtr<SharedBuffer> buffer)
+    : m_fontName(strdup(fontName))
+    , m_buffer(buffer)
+{
+}
+
+FontCustomPlatformData::~FontCustomPlatformData()
+{
+    FS_LONG ret = FS_delete_font(BlackBerry::Platform::Graphics::getIType(), const_cast<FILECHAR*>(m_fontName));
+    ASSERT_UNUSED(ret, ret == SUCCESS);
+    free(m_fontName);
+}
+
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool syntheticBold, bool syntheticItalic, FontOrientation orientation, TextOrientation textOrientation, FontWidthVariant widthVariant, FontRenderingMode)
+{
+    return FontPlatformData(m_fontName, size, syntheticBold, syntheticItalic, orientation, textOrientation, widthVariant);
+}
+
+bool FontCustomPlatformData::supportsFormat(const String& format)
+{
+    bool isSupported = equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype");
+#if USE(OPENTYPE_SANITIZER)
+    isSupported = isSupported || equalIgnoringCase(format, "woff");
+#endif
+    return isSupported;
+}
+
+FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
+{
+    ASSERT_ARG(buffer, buffer);
+
+#if USE(OPENTYPE_SANITIZER)
+    OpenTypeSanitizer sanitizer(buffer);
+    RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize();
+    if (!transcodeBuffer)
+        return 0; // validation failed.
+    buffer = transcodeBuffer.get();
+#endif
+
+    FILECHAR name[MAX_FONT_NAME_LEN+1];
+    memset(name, 0, MAX_FONT_NAME_LEN+1);
+    if (FS_load_font(BlackBerry::Platform::Graphics::getIType(), 0, const_cast<FS_BYTE*>(reinterpret_cast<const FS_BYTE*>(buffer->data())), 0, MAX_FONT_NAME_LEN, name) != SUCCESS)
+        return 0;
+
+    return new FontCustomPlatformData(name, buffer);
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/blackberry/FontPlatformDataBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/FontPlatformDataBlackBerry.cpp
new file mode 100644 (file)
index 0000000..604d0e1
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2012, 2013 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "FontPlatformData.h"
+
+#include "HarfBuzzNGFace.h"
+#include "ITypeUtils.h"
+
+#include <BlackBerryPlatformGraphicsContext.h>
+#include <fs_api.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+FontPlatformData::FontPlatformData(FILECHAR* name, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, TextOrientation textOrientation, FontWidthVariant widthVariant)
+    : m_syntheticBold(syntheticBold)
+    , m_syntheticOblique(syntheticOblique)
+    , m_orientation(orientation)
+    , m_textOrientation(textOrientation)
+    , m_size(size)
+    , m_widthVariant(widthVariant)
+    , m_font(0)
+    , m_name(fastStrDup(name))
+    , m_scaledFont(0)
+    , m_harfbuzzFace()
+    , m_isColorBitmapFont(false)
+{
+    ASSERT(name);
+    m_font = FS_new_client(BlackBerry::Platform::Graphics::getIType(), 0);
+    ASSERT(m_font);
+    applyState(m_font);
+}
+
+FontPlatformData::~FontPlatformData()
+{
+    if (m_scaledFont) {
+        BlackBerry::Platform::Graphics::clearGlyphCacheForFont(m_scaledFont);
+        FS_end_client(m_scaledFont);
+    }
+    if (m_font && m_font != hashTableDeletedFontValue())
+        FS_end_client(m_font);
+    fastFree(m_name);
+}
+
+const char* FontPlatformData::name() const
+{
+    return m_name;
+}
+
+bool FontPlatformData::applyState(FS_STATE* font, float scale) const
+{
+    ASSERT(font);
+    ASSERT(m_name);
+    if (FS_set_font(font, m_name) != SUCCESS)
+        return false;
+
+    if (FS_set_cmap(font, 3, 10) != SUCCESS) // First try Windows Unicode with surrogates...
+        if (FS_set_cmap(font, 3, 1) != SUCCESS) // try normal Windows Unicode
+            if (FS_set_cmap(font, 1, 0) != SUCCESS)
+                return false;
+
+    if (m_syntheticBold) {
+        if (FS_set_bold_pct(font, floatToITypeFixed(0.06)) != SUCCESS) // 6% pseudo bold
+            return false;
+    } else {
+        if (FS_set_bold_pct(font, 0) != SUCCESS)
+            return false;
+    }
+
+    FS_FIXED skew = 0;
+    if (m_syntheticOblique)
+        skew = 13930; // 12 degrees
+
+    FS_FIXED fixedScale = std::min(FixMul(floatToITypeFixed(scale), floatToITypeFixed(m_size)), MAXITYPEFONTSCALE);
+    if (FS_set_scale(font, fixedScale, FixMul(fixedScale, skew), 0, fixedScale) != SUCCESS)
+        return false;
+
+    if (FS_set_flags(font, FLAGS_CMAP_OFF) != SUCCESS)
+        return false;
+
+    if (FS_set_flags(font, FLAGS_HINTS_OFF) != SUCCESS)
+        return false;
+
+    if (FS_set_flags(font, FLAGS_DEFAULT_CSM_OFF) != SUCCESS)
+        return false;
+
+    if (m_orientation == Vertical) {
+        if (FS_set_flags(font, (m_textOrientation == TextOrientationVerticalRight) ? FLAGS_VERTICAL_ROTATE_LEFT_ON : FLAGS_VERTICAL_ON) != SUCCESS)
+            return false;
+    }
+    return true;
+}
+
+void FontPlatformData::platformDataInit(const FontPlatformData& source)
+{
+    m_harfbuzzFace = source.m_harfbuzzFace;
+    m_scaledFont = 0;
+    if (source.m_font && source.m_font != hashTableDeletedFontValue()) {
+        m_font = FS_new_client(source.m_font, 0);
+        m_name = fastStrDup(source.name());
+        bool ret = applyState(m_font);
+        ASSERT_UNUSED(ret, ret);
+    } else
+        m_font = source.m_font;
+}
+
+const FontPlatformData& FontPlatformData::platformDataAssign(const FontPlatformData& other)
+{
+    m_harfbuzzFace = other.m_harfbuzzFace;
+    m_scaledFont = 0;
+    if (other.m_font && other.m_font != hashTableDeletedFontValue()) {
+        m_font = FS_new_client(other.m_font, 0);
+        fastFree(m_name);
+        m_name = fastStrDup(other.name());
+        bool ret = applyState(m_font);
+        ASSERT_UNUSED(ret, ret);
+    } else
+        m_font = other.m_font;
+
+    return *this;
+}
+
+bool FontPlatformData::platformIsEqual(const FontPlatformData& other) const
+{
+    if (m_font == other.m_font)
+        return true;
+
+    if (!m_font || m_font == hashTableDeletedFontValue() || !other.m_font || other.m_font == hashTableDeletedFontValue())
+        return false;
+
+    return m_font->cur_sfnt == other.m_font->cur_sfnt;
+}
+
+#ifndef NDEBUG
+String FontPlatformData::description() const
+{
+    return "iType Font Data";
+}
+#endif
+
+HarfBuzzNGFace* FontPlatformData::harfbuzzFace()
+{
+    if (!m_harfbuzzFace) {
+        uint64_t uniqueID = reinterpret_cast<uintptr_t>(m_font);
+        m_harfbuzzFace = HarfBuzzNGFace::create(const_cast<FontPlatformData*>(this), uniqueID);
+    }
+
+    return m_harfbuzzFace.get();
+}
+
+FS_STATE* FontPlatformData::scaledFont(float scale) const
+{
+    ASSERT(scale > 0.0);
+    if (m_scale == scale && m_scaledFont)
+        return m_scaledFont;
+
+    // This must be an SVG Font. It seems like there is an upstream bug where web and SVG fonts
+    // are used in one TextRun. Other ports seem to be able to deal with having an SVG Font in
+    // this path so bail out instead of crash.
+    if (!m_font)
+        return 0;
+
+    if (m_scaledFont) {
+        BlackBerry::Platform::Graphics::clearGlyphCacheForFont(m_scaledFont);
+        if (FS_end_client(m_scaledFont) != SUCCESS)
+            CRASH();
+    }
+
+    m_scaledFont = FS_new_client(m_font, 0);
+    if (!applyState(m_scaledFont, scale)) {
+        if (FS_end_client(m_scaledFont) != SUCCESS)
+            CRASH();
+        m_scaledFont = 0;
+        return 0;
+    }
+
+    m_scale = scale;
+
+    return m_scaledFont;
+}
+
+void FontPlatformData::setFakeBold(bool fakeBold)
+{
+    m_syntheticBold = fakeBold;
+    applyState(m_font);
+}
+
+void FontPlatformData::setFakeItalic(bool fakeItalic)
+{
+    m_syntheticOblique = fakeItalic;
+    applyState(m_font);
+}
+
+const void* FontPlatformData::platformFontHandle() const
+{
+    ASSERT(m_font);
+    return m_font->cur_sfnt;
+}
+
+bool FontPlatformData::isFixedPitch() const
+{
+    TTF_POST post;
+    if (m_font && FS_get_table_structure(m_font, TAG_post, &post) == SUCCESS)
+        return post.isFixedPitch;
+    return false;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/blackberry/GlyphPageTreeNodeBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/GlyphPageTreeNodeBlackBerry.cpp
new file mode 100644 (file)
index 0000000..406003a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "GlyphPageTreeNode.h"
+
+#include "SimpleFontData.h"
+#include <fs_api.h>
+
+namespace WebCore {
+
+template<typename T>
+class WorldTypeScopedPtr {
+public:
+    typedef void (*DestroyFunction)(T*);
+
+    WorldTypeScopedPtr(T* ptr, DestroyFunction destroy)
+        : m_ptr(ptr)
+        , m_destroy(destroy)
+    {
+        ASSERT(m_destroy);
+    }
+    ~WorldTypeScopedPtr()
+    {
+        if (m_ptr)
+            (*m_destroy)(m_ptr);
+    }
+
+    T* get() { return m_ptr; }
+private:
+    T* m_ptr;
+    DestroyFunction m_destroy;
+};
+
+bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
+{
+    bool haveGlyphs = false;
+    unsigned position = 0;
+    int i = 0;
+    while (position < bufferLength) {
+        UChar32 character;
+        unsigned nextPosition = position;
+        U16_NEXT(buffer, nextPosition, bufferLength, character);
+
+        FS_USHORT glyph = FS_map_char(fontData->platformData().font(), static_cast<FS_ULONG>(character));
+        if (!glyph)
+            setGlyphDataForIndex(offset + i, 0, 0);
+        else {
+            haveGlyphs = true;
+            setGlyphDataForIndex(offset + i, glyph, fontData);
+        }
+
+        i++;
+        position = nextPosition;
+    }
+
+    return haveGlyphs;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/blackberry/GradientBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/GradientBlackBerry.cpp
new file mode 100644 (file)
index 0000000..a3848f0
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "config.h"
+#include "Gradient.h"
+
+#include "AffineTransform.h"
+#include "GraphicsContext.h"
+#include "GraphicsContext3D.h"
+#include "KURL.h"
+#include "NotImplemented.h"
+#include "TransformationMatrix.h"
+
+#include <BlackBerryPlatformGraphicsContext.h>
+#include <stdio.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/UnusedParam.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// Determine the total number of stops needed, including pseudo-stops at the
+// ends as necessary.
+static size_t totalStopsNeeded(const Gradient::ColorStop* stopData, size_t count)
+{
+    // N.B.: The tests in this function should kept in sync with the ones in
+    // fillStops(), or badness happens.
+    const Gradient::ColorStop* stop = stopData;
+    size_t countUsed = count;
+    if (count < 1 || stop->stop > 0.0)
+        countUsed++;
+    stop += count - 1;
+    if (count < 1 || stop->stop < 1.0)
+        countUsed++;
+    return countUsed;
+}
+
+// Collect sorted stop position and color information into the pos and colors
+// buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large
+// enough to hold information for all stops, including the new endpoints if
+// stops at 0.0 and 1.0 aren't already included.
+static void fillStops(const Gradient::ColorStop* stopData, size_t count, float* pos, unsigned* colors)
+{
+    const Gradient::ColorStop* stop = stopData;
+    size_t start = 0;
+    if (count < 1) {
+        // A gradient with no stops must be transparent black.
+        pos[0] = 0.0;
+        colors[0] = 0;
+        start = 1;
+    } else if (stop->stop > 0.0) {
+        // Copy the first stop to 0.0. The first stop position may have a slight
+        // rounding error, but we don't care in this float comparison, since
+        // 0.0 comes through cleanly and people aren't likely to want a gradient
+        // with a stop at (0 + epsilon).
+        pos[0] = 0.0;
+        colors[0] = Color(stop->red, stop->green, stop->blue, stop->alpha).rgb();
+        start = 1;
+    }
+
+    for (size_t i = start; i < start + count; i++) {
+        pos[i] = stop->stop;
+        colors[i] = Color(stop->red, stop->green, stop->blue, stop->alpha).rgb();
+        ++stop;
+    }
+
+    // Copy the last stop to 1.0 if needed. See comment above about this float
+    // comparison.
+    if (count < 1 || (--stop)->stop < 1.0) {
+        pos[start + count] = 1.0;
+        colors[start + count] = colors[start + count - 1];
+    }
+}
+
+
+BlackBerry::Platform::Graphics::Gradient* Gradient::platformGradient()
+{
+    if (m_gradient)
+        return m_gradient;
+
+    if (m_radial)
+        m_gradient = BlackBerry::Platform::Graphics::Gradient::createRadialGradient(m_p0, m_p1, m_r0, m_r1, m_aspectRatio, (BlackBerry::Platform::Graphics::Gradient::SpreadMethod)m_spreadMethod);
+    else
+        m_gradient = BlackBerry::Platform::Graphics::Gradient::createLinearGradient(m_p0, m_p1, (BlackBerry::Platform::Graphics::Gradient::SpreadMethod)m_spreadMethod);
+
+    sortStopsIfNecessary();
+    ASSERT(m_stopsSorted);
+
+    size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size());
+    ASSERT(countUsed >= 2);
+    ASSERT(countUsed >= m_stops.size());
+
+    Vector<float> pos(countUsed);
+    Vector<unsigned> colors(countUsed);
+    fillStops(m_stops.data(), m_stops.size(), pos.data(), colors.data());
+    m_gradient->setColorStops(pos.data(), colors.data(), countUsed);
+
+    if (!m_gradientSpaceTransformation.isIdentity())
+        m_gradient->setLocalMatrix(reinterpret_cast<const double*>(&m_gradientSpaceTransformation));
+
+    return m_gradient;
+}
+
+void Gradient::platformDestroy()
+{
+    delete m_gradient;
+    m_gradient = 0;
+}
+
+void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
+{
+    platformGradient()->fill(context->platformContext(), rect);
+}
+
+void Gradient::setPlatformGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
+{
+    platformGradient()->setLocalMatrix(reinterpret_cast<const double*>(&gradientSpaceTransformation));
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/blackberry/GraphicsContextBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/GraphicsContextBlackBerry.cpp
new file mode 100644 (file)
index 0000000..c29f86d
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "config.h"
+#include "GraphicsContext.h"
+
+#include "AffineTransform.h"
+#include "Gradient.h"
+#include "GraphicsContext3D.h"
+#include "KURL.h"
+#include "NotImplemented.h"
+#include "TransformationMatrix.h"
+
+#include <BlackBerryPlatformGraphicsContext.h>
+#include <stdio.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/UnusedParam.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class GraphicsContextPlatformPrivate {
+public:
+    GraphicsContextPlatformPrivate(PlatformGraphicsContext* platformContext)
+        : m_platformContext(platformContext)
+        , m_isComposited(false)
+    {
+    }
+
+    PlatformGraphicsContext* m_platformContext;
+    bool m_isComposited;
+};
+
+void GraphicsContext::platformInit(PlatformGraphicsContext* platformContext)
+{
+    m_data = new GraphicsContextPlatformPrivate(platformContext);
+}
+
+void GraphicsContext::platformDestroy()
+{
+    delete m_data;
+}
+
+PlatformGraphicsContext* GraphicsContext::platformContext() const
+{
+    return m_data->m_platformContext;
+}
+
+void GraphicsContext::savePlatformState()
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->save();
+}
+
+void GraphicsContext::restorePlatformState()
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->restore();
+    platformContext()->setFillColor(m_state.fillColor.rgb());
+    if (hasShadow())
+        setPlatformShadow(m_state.shadowOffset, m_state.shadowBlur, m_state.shadowColor, m_state.shadowColorSpace);
+    else
+        clearPlatformShadow();
+    platformContext()->setStrokeColor(m_state.strokeColor.rgb());
+    platformContext()->setStrokeStyle(static_cast<BlackBerry::Platform::Graphics::StrokeStyle>(m_state.strokeStyle));
+    platformContext()->setStrokeThickness(m_state.strokeThickness);
+    platformContext()->setTextDrawingMode(m_state.textDrawingMode);
+}
+
+void GraphicsContext::setIsAcceleratedContext(bool accelerated)
+{
+    m_data->m_isComposited = accelerated;
+}
+
+bool GraphicsContext::isAcceleratedContext() const
+{
+    return m_data->m_isComposited;
+}
+
+AffineTransform GraphicsContext::getCTM(IncludeDeviceScale) const
+{
+    if (paintingDisabled())
+        return AffineTransform();
+
+    AffineTransform result;
+    platformContext()->getTransform((double*)&result);
+    return result;
+}
+
+void GraphicsContext::concatCTM(const AffineTransform& transformation)
+{
+    if (paintingDisabled())
+        return;
+
+    AffineTransform current;
+    platformContext()->getTransform((double*)&current);
+    current *= transformation;
+    platformContext()->setTransform((double*)&current);
+}
+
+void GraphicsContext::setCTM(const AffineTransform& transformation)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setTransform((const double*)&transformation);
+}
+
+void GraphicsContext::scale(const FloatSize& scaleFactors)
+{
+    if (paintingDisabled())
+        return;
+
+    AffineTransform current;
+    platformContext()->getTransform((double*)&current);
+    current.scaleNonUniform(scaleFactors.width(), scaleFactors.height());
+    platformContext()->setTransform((double*)&current);
+}
+
+void GraphicsContext::rotate(float radians)
+{
+    if (paintingDisabled())
+        return;
+
+    AffineTransform current;
+    platformContext()->getTransform((double*)&current);
+    current.rotate(rad2deg(radians));
+    platformContext()->setTransform((double*)&current);
+}
+
+void GraphicsContext::translate(float dx, float dy)
+{
+    if (paintingDisabled())
+        return;
+
+    AffineTransform current;
+    platformContext()->getTransform((double*)&current);
+    current.translate(dx, dy);
+    platformContext()->setTransform((double*)&current);
+}
+
+void GraphicsContext::drawEllipse(const IntRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->addEllipse(FloatRect(rect));
+}
+
+void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->addArc(rect, startAngle, angleSpan);
+}
+
+void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->addConvexPolygon(numPoints, (const BlackBerry::Platform::FloatPoint*)points);
+}
+
+void GraphicsContext::drawRect(const IntRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->addDrawRect(FloatRect(rect));
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    BlackBerry::Platform::Graphics::Gradient* platformGradient = fillGradient() ? fillGradient()->platformGradient() : 0;
+    BlackBerry::Platform::Graphics::Pattern* platformPattern = fillPattern() ? fillPattern()->platformPattern(AffineTransform()) : 0;
+    platformContext()->addFillRect(rect, platformGradient, platformPattern);
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setFillColor(color.rgb());
+    platformContext()->addFillRect(rect);
+    platformContext()->setFillColor(m_state.fillColor.rgb());
+}
+
+void GraphicsContext::clearRect(const FloatRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->addClearRect(rect);
+}
+
+void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
+{
+    if (paintingDisabled())
+        return;
+
+    if (strokeGradient() || strokePattern()) {
+        Path path;
+        path.addRect(rect);
+        float oldLineWidth = m_state.strokeThickness;
+        setPlatformStrokeThickness(lineWidth);
+        strokePath(path);
+        setPlatformStrokeThickness(oldLineWidth);
+    } else
+        platformContext()->addStrokeRect(rect, lineWidth);
+}
+
+void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    BlackBerry::Platform::FloatRoundedRect r = BlackBerry::Platform::FloatRoundedRect(FloatRect(rect), FloatSize(topLeft), FloatSize(topRight), FloatSize(bottomLeft), FloatSize(bottomRight));
+    platformContext()->setFillColor(color.rgb());
+    platformContext()->addRoundedRect(r);
+    platformContext()->setFillColor(m_state.fillColor.rgb());
+}
+
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode roundingMode)
+{
+    return rect;
+}
+
+void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    FloatSize adjustedOffset = offset;
+
+    if (m_state.shadowsIgnoreTransforms) {
+        // Meaning that this graphics context is associated with a CanvasRenderingContext
+        // We flip the height since CG and HTML5 Canvas have opposite Y axis
+        adjustedOffset.setHeight(-offset.height());
+    }
+
+    // if there is an invalid shadow color, we're supposed to use Apple's CG default
+    platformContext()->setShadow(adjustedOffset, blur, color.isValid() ? color.rgb() : makeRGBA(0, 0, 0, 0xFF / 3), m_state.shadowsIgnoreTransforms);
+}
+
+void GraphicsContext::clearPlatformShadow()
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->clearShadow();
+}
+
+void GraphicsContext::beginPlatformTransparencyLayer(float opacity)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->beginPlatformTransparencyLayer(opacity);
+}
+
+void GraphicsContext::endPlatformTransparencyLayer()
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->endPlatformTransparencyLayer();
+}
+
+bool GraphicsContext::supportsTransparencyLayers()
+{
+    return true;
+}
+
+void GraphicsContext::setLineCap(LineCap lc)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setLineCap((BlackBerry::Platform::Graphics::LineCap)lc);
+}
+
+void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setLineDash(dashes.data(), dashes.size(), dashOffset);
+}
+
+void GraphicsContext::setLineJoin(LineJoin lj)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setLineJoin((BlackBerry::Platform::Graphics::LineJoin)lj); // naming coincides
+}
+
+void GraphicsContext::setMiterLimit(float limit)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setMiterLimit(limit);
+}
+
+void GraphicsContext::setAlpha(float opacity)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setAlpha(opacity);
+}
+
+
+void GraphicsContext::clip(const FloatRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->clip(rect);
+}
+
+void GraphicsContext::clipOut(const IntRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->clipOut(FloatRect(rect));
+}
+
+void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialias)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->clipConvexPolygon(numPoints, (const BlackBerry::Platform::FloatPoint*)points);
+}
+
+void GraphicsContext::addRoundedRectClip(const RoundedRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    BlackBerry::Platform::FloatRoundedRect r = BlackBerry::Platform::FloatRoundedRect(
+        FloatRect(rect.rect()),
+        FloatSize(rect.radii().topLeft()),
+        FloatSize(rect.radii().topRight()),
+        FloatSize(rect.radii().bottomLeft()),
+        FloatSize(rect.radii().bottomRight()));
+    platformContext()->clipRoundedRect(r);
+}
+
+void GraphicsContext::clipOutRoundedRect(const RoundedRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    BlackBerry::Platform::FloatRoundedRect r = BlackBerry::Platform::FloatRoundedRect(
+        FloatRect(rect.rect()),
+        FloatSize(rect.radii().topLeft()),
+        FloatSize(rect.radii().topRight()),
+        FloatSize(rect.radii().bottomLeft()),
+        FloatSize(rect.radii().bottomRight()));
+    platformContext()->clipOutRoundedRect(r);
+}
+
+IntRect GraphicsContext::clipBounds() const
+{
+    // FIXME: return the max IntRect for now
+    return IntRect(IntPoint(INT_MIN / 2, INT_MIN / 2), IntSize(INT_MAX, INT_MAX));
+}
+
+
+void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
+{
+    if (paintingDisabled())
+        return;
+
+    fprintf(stderr, "clip rounded rect %d,%d,%d,%d - %d\n", rect.x(), rect.y(), rect.width(), rect.height(), thickness);
+}
+
+void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
+{
+}
+
+void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setTextDrawingMode(mode);
+}
+
+void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setStrokeColor(color.rgb());
+}
+
+void GraphicsContext::setPlatformStrokeStyle(StrokeStyle stroke)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setStrokeStyle((BlackBerry::Platform::Graphics::StrokeStyle)stroke);
+}
+
+void GraphicsContext::setPlatformStrokeThickness(float thickness)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setStrokeThickness(thickness);
+}
+
+void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setFillColor(color.rgb());
+}
+
+void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setCompositeOperation(static_cast<BlackBerry::Platform::Graphics::CompositeOperator>(op));
+}
+
+void GraphicsContext::setPlatformShouldAntialias(bool enable)
+{
+    if (paintingDisabled())
+        return;
+
+    platformContext()->setUseAntialiasing(enable);
+}
+
+void GraphicsContext::setImageInterpolationQuality(InterpolationQuality interpolationQuality)
+{
+    platformContext()->setHighQualityFilter(interpolationQuality != InterpolationNone);
+}
+
+InterpolationQuality GraphicsContext::imageInterpolationQuality() const
+{
+    return platformContext()->highQualityFilter() ? InterpolationDefault : InterpolationNone;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/blackberry/ITypeUtils.h b/Source/WebCore/platform/graphics/blackberry/ITypeUtils.h
new file mode 100644 (file)
index 0000000..f614f22
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Research In Motion Limited nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ITypeUtils_h
+#define ITypeUtils_h
+
+#include <fs_api.h>
+
+static inline FS_FIXED floatToITypeFixed(float f) { return static_cast<FS_FIXED>(f * 65536.0); }
+static inline FS_FIXED intToITypeFixed(int i) { return static_cast<FS_FIXED>(i << 16); }
+
+static inline float iTypeFixedToFloat(FS_FIXED n) { return n / 65536.0; }
+
+static const FS_FIXED MAXITYPEFONTSCALE = intToITypeFixed(10000) - 1;
+
+#endif // ITypeUtils_h
diff --git a/Source/WebCore/platform/graphics/blackberry/ImageBufferBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/ImageBufferBlackBerry.cpp
new file mode 100644 (file)
index 0000000..0a09b58
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "config.h"
+#include "ImageBuffer.h"
+
+#include "Base64.h"
+#include "BitmapImage.h"
+#include "HostWindow.h"
+#include "ImageData.h"
+#include "JPEGImageEncoder.h"
+#include "LayerMessage.h"
+#include "PNGImageEncoder.h"
+#include "TiledImage.h"
+
+#include <BlackBerryPlatformGLES2ContextState.h>
+#include <BlackBerryPlatformGraphics.h>
+#include <BlackBerryPlatformGraphicsContext.h>
+#include <BlackBerryPlatformSettings.h>
+#include <BlackBerryPlatformWindow.h>
+#include <wtf/text/WTFString.h>
+
+using namespace std;
+
+namespace WebCore {
+
+static bool makeBufferCurrent(HostWindow* window)
+{
+    ASSERT(isCompositingThread());
+
+    if (window && window->platformPageClient()) {
+        if (BlackBerry::Platform::Graphics::Window* platformWindow = window->platformPageClient()->platformWindow()) {
+            if (BlackBerry::Platform::Graphics::makeBufferCurrent(platformWindow->buffer(), BlackBerry::Platform::Graphics::GLES2))
+                return true;
+        }
+    }
+
+    // If we don't have a window but the application state saver is enabled,
+    // we're using a BlackBerry::WebKit::WebPageCompositor for rendering,
+    // that makes sure a context is always current on the compositing thread.
+    if (BlackBerry::Platform::Settings::isGLES2AppStateSaverEnabled())
+        return true;
+
+    // Otherwise, we'll have to try and fall back to our last hope.
+    return BlackBerry::Platform::Graphics::makeSharedResourceContextCurrent(BlackBerry::Platform::Graphics::GLES2);
+}
+
+static bool getImageDataInternal(GraphicsContext* context, const IntRect& rect, const IntRect& size, unsigned char* result, bool unmultiply, HostWindow* window)
+{
+    if (!makeBufferCurrent(window)) {
+        BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelWarn,
+            "ImageBufferBlackBerry getImageDataInternal() error: cannot make buffer current, returning zeroed-out pixels.");
+        memset(result, 0, rect.width() * rect.height() * 4);
+        return false;
+    }
+
+    // readPixels can call updateBacking which draws the display list. This is out-of-band rendering and we need
+    // to protect the embedder from state mutations.
+    BlackBerry::Platform::Graphics::GLES2ContextState::AppStateSaver appStateSaver;
+
+    // Any pixels outside the canvas are returned as transparent black in the resulting ImageData object.
+    if (rect.x() < 0
+        || rect.y() < 0
+        || rect.maxX() > size.width()
+        || rect.maxY() > size.height())
+        memset(result, 0, rect.width() * rect.height() * 4);
+
+    IntRect subrect = rect;
+    subrect.intersect(size);
+    // nothing to do if rect is completely outside of the image area
+    if (subrect.isEmpty())
+        return true;
+    // adjust for negative x and y index
+    if (rect.x() < 0)
+        result += (-rect.x() * 4);
+    if (rect.y() < 0)
+        result += (-rect.y() * rect.width() * 4);
+
+    // FIXME: We need to implement a tiled buffer.
+    const int maxTileSize = BlackBerry::Platform::Graphics::TiledImage::defaultTileSize();
+    IntRect r = subrect;
+    IntRect tileRect(0, 0, maxTileSize, maxTileSize);
+    r.intersect(tileRect);
+    if (!r.isEmpty())
+        context->platformContext()->readPixels(r, result, unmultiply);
+    return true;
+}
+
+void ImageBufferData::getImageData(GraphicsContext* context, const IntRect& rect, const IntRect& size, unsigned char* result, bool unmultiply) const
+{
+    if (!isCompositingThread()) {
+        // Use createFunctionCallMessage instead of createMethodCallMessage to avoid deadlock
+        // with Guarded pointers.
+        dispatchSyncCompositingMessage(BlackBerry::Platform::createFunctionCallMessage(
+            &getImageDataInternal, context, rect, size, result, unmultiply, m_window));
+        return;
+    }
+
+    getImageDataInternal(context, rect, size, result, unmultiply, m_window);
+}
+
+static bool flushAndDraw(const ImageBufferData* object, GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale)
+{
+    if (!makeBufferCurrent(object->m_window)) {
+        BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelWarn,
+            "ImageBufferBlackBerry flushAndDraw() error: cannot make buffer current, ignoring call.");
+        return false;
+    }
+
+    using namespace BlackBerry::Platform::Graphics;
+
+    // flushAndDrawBuffer calls updateBacking which draws the display list. This is out-of-band rendering and we need
+    // to protect the embedder from state mutations.
+    BlackBerry::Platform::Graphics::GLES2ContextState::AppStateSaver appStateSaver;
+
+    CompositeOperator oldOperator = context->compositeOperation();
+    context->setCompositeOperation(op);
+    context->platformContext()->flushAndDrawBuffer(object->m_buffer, destRect, srcRect);
+    context->setCompositeOperation(oldOperator);
+    return true;
+}
+
+void ImageBufferData::draw(GraphicsContext* thisContext, GraphicsContext* otherContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale) const
+{
+    const FloatRect normDestRect = destRect.normalized();
+    const FloatRect normSrcRect = srcRect.normalized();
+
+    if (normSrcRect.isEmpty() || normDestRect.isEmpty())
+        return; // Nothing to draw.
+
+    if (thisContext->platformContext()->isEmpty() && platformBufferHandle(m_buffer)) {
+        CompositeOperator oldOperator = otherContext->compositeOperation();
+        otherContext->setCompositeOperation(op);
+        otherContext->platformContext()->drawBuffer(m_buffer, normDestRect, normSrcRect);
+        otherContext->setCompositeOperation(oldOperator);
+    } else {
+        dispatchSyncCompositingMessage(BlackBerry::Platform::createFunctionCallMessage(
+            &flushAndDraw, this, otherContext, styleColorSpace, normDestRect, normSrcRect, op, useLowQualityScale));
+    }
+}
+
+ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace colorSpace, RenderingMode renderingMode, DeferralMode deferralMode, HostWindow* window, bool& success)
+    : m_size(size)
+    , m_logicalSize(size)
+    , m_resolutionScale(1)
+{
+    success = false;
+
+    // There is no explicitly defined default ctor for ImageBufferData::m_data,
+    // on purpose - precaution. Hence upon creation m_data will contain garbage
+    // leading to crash up dtor. To avoid the case, initilize it explicitly.
+    m_data.m_buffer = 0;
+    m_data.m_platformLayer = nullptr;
+    m_data.m_window = 0;
+
+    // anything bigger then defaultTileSize is just a problem for the HW.
+    const int maxTileSize = BlackBerry::Platform::Graphics::TiledImage::defaultTileSize();
+    if (maxTileSize <= size.width() || maxTileSize <= size.height()) {
+        BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelWarn, "Requested ImageBuffer size [%d %d] is too big. HW allows up to [%d %d].",
+            size.width(), size.height(), maxTileSize, maxTileSize);
+    }
+
+    m_data.m_buffer = BlackBerry::Platform::Graphics::createBuffer(m_size, BlackBerry::Platform::Graphics::AlwaysBacked);
+    m_data.m_platformLayer = CanvasLayerWebKitThread::create(m_data.m_buffer, m_size);
+    m_data.m_window = window;
+    m_context = adoptPtr(new GraphicsContext(lockBufferDrawable(m_data.m_buffer)));
+    m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale));
+    m_context->setIsAcceleratedContext(renderingMode == Accelerated);
+    success = true;
+}
+
+ImageBuffer::~ImageBuffer()
+{
+    m_context.clear();
+
+    // Ensure that we clear the buffer in the compositing thread before the buffer is destroyed.
+    if (m_data.m_platformLayer) {
+        dispatchSyncCompositingMessage(BlackBerry::Platform::createFunctionCallMessage(
+            &CanvasLayerWebKitThread::clearBuffer, m_data.m_platformLayer.get()));
+    }
+
+    BlackBerry::Platform::Graphics::destroyBuffer(m_data.m_buffer);
+    m_data.m_buffer = 0;
+}
+
+GraphicsContext* ImageBuffer::context() const
+{
+    return m_context.get();
+}
+
+PlatformLayer* ImageBuffer::platformLayer() const
+{
+    return m_data.m_platformLayer.get();
+}
+
+PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const
+{
+    // FIXME respect copyBehaviour enum.
+    unsigned* imageData = new unsigned[m_size.width() * m_size.height()];
+    m_data.getImageData(m_context.get(), IntRect(IntPoint(0, 0), m_size), IntRect(IntPoint(0, 0), m_size), (unsigned char*)imageData, false /* unmultiply */);
+    BlackBerry::Platform::Graphics::TiledImage* nativeImage = new BlackBerry::Platform::Graphics::TiledImage(m_size, imageData, false /* dataIsBGRA */);
+    return BitmapImage::create(nativeImage);
+}
+
+void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const
+{
+    WTF_ALIGNED(unsigned char*, imageData, 4) = new unsigned char[m_size.width() * m_size.height() * 4];
+    m_data.getImageData(m_context.get(), IntRect(IntPoint(0, 0), m_size), IntRect(IntPoint(0, 0), m_size), imageData, false /* unmultiply */);
+    BlackBerry::Platform::Graphics::TiledImage* nativeImage = new BlackBerry::Platform::Graphics::TiledImage(m_size, reinterpret_cast_ptr<unsigned*>(imageData), false /* dataIsBGRA */);
+    context->platformContext()->addMaskLayer(rect, nativeImage);
+}
+
+void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale)
+{
+    m_data.draw(m_context.get(), context, styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+}
+
+void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
+{
+    RefPtr<Image> image = copyImage(DontCopyBackingStore);
+    image->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
+}
+
+void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
+{
+}
+
+PassRefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, CoordinateSystem) const
+{
+    RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(rect.width() * rect.height() * 4);
+    m_data.getImageData(m_context.get(), rect, IntRect(IntPoint(0, 0), m_size), result->data(), true);
+    return result;
+}
+
+PassRefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, CoordinateSystem) const
+{
+    RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(rect.width() * rect.height() * 4);
+    m_data.getImageData(m_context.get(), rect, IntRect(IntPoint(0, 0), m_size), result->data(), false);
+    return result;
+}
+
+void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem)
+{
+    BlackBerry::Platform::Graphics::TiledImage image(sourceSize, reinterpret_cast_ptr<unsigned*>(source->data()), false /* this data is RGBA, not BGRA */, multiplied == Premultiplied);
+    m_context->platformContext()->save();
+    const double matrix[] = { 1., 0., 0., 1., 0., 0. };
+    m_context->platformContext()->setTransform(matrix);
+    m_context->platformContext()->setAlpha(1.0);
+    m_context->platformContext()->resetClip();
+    m_context->platformContext()->setCompositeOperation(BlackBerry::Platform::Graphics::CompositeCopy);
+    m_context->platformContext()->addImage(FloatRect(destPoint + sourceRect.location(), sourceRect.size()), FloatRect(sourceRect), &image);
+    m_context->platformContext()->restore();
+}
+
+String ImageBuffer::toDataURL(const String& mimeType, const double* quality, CoordinateSystem) const
+{
+    if (m_size.isEmpty())
+        return "data:,";
+
+    enum {
+        EncodeJPEG,
+        EncodePNG,
+    } encodeType = mimeType.lower() == "image/png" ? EncodePNG : EncodeJPEG;
+
+    // According to http://www.w3.org/TR/html5/the-canvas-element.html,
+    // "For image types that do not support an alpha channel, the image must be"
+    // "composited onto a solid black background using the source-over operator,"
+    // "and the resulting image must be the one used to create the data: URL."
+    // JPEG doesn't have alpha channel, so we need premultiplied data.
+    RefPtr<Uint8ClampedArray> imageData = encodeType == EncodePNG
+        ? getUnmultipliedImageData(IntRect(IntPoint(0, 0), m_size))
+        : getPremultipliedImageData(IntRect(IntPoint(0, 0), m_size));
+
+    Vector<char> output;
+    const char* header;
+    if (encodeType == EncodePNG) {
+        if (!compressRGBABigEndianToPNG(imageData->data(), m_size, output))
+            return "data:,";
+        header = "data:image/png;base64,";
+    } else {
+        if (!compressRGBABigEndianToJPEG(imageData->data(), m_size, output, quality))
+            return "data:,";
+        header = "data:image/jpeg;base64,";
+    }
+
+    Vector<char> base64;
+    base64Encode(output, base64);
+
+    output.clear();
+
+    Vector<char> url;
+    url.append(header, strlen(header));
+    url.append(base64);
+
+    return String(url.data(), url.size());
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/blackberry/ImageBufferDataBlackBerry.h b/Source/WebCore/platform/graphics/blackberry/ImageBufferDataBlackBerry.h
new file mode 100644 (file)
index 0000000..8da330e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef ImageBufferDataBlackBerry_h
+#define ImageBufferDataBlackBerry_h
+
+#include "CanvasLayerWebKitThread.h"
+#include "GraphicsContext.h"
+
+#include <BlackBerryPlatformGraphics.h>
+#include <BlackBerryPlatformGuardedPointer.h>
+#include <wtf/Uint8ClampedArray.h>
+
+namespace WebCore {
+
+class GraphicsContext;
+class IntRect;
+class HostWindow;
+
+class ImageBufferData {
+public:
+    void getImageData(GraphicsContext*, const IntRect&, const IntRect&, unsigned char* result, bool unmultiply) const;
+    void draw(GraphicsContext* thisContext, GraphicsContext* otherContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, bool useLowQualityScale) const;
+
+    BlackBerry::Platform::Graphics::Buffer* m_buffer;
+    RefPtr<CanvasLayerWebKitThread> m_platformLayer;
+    HostWindow* m_window;
+};
+
+} // namespace WebCore
+
+#endif // ImageBufferDataBlackBerry_h
diff --git a/Source/WebCore/platform/graphics/blackberry/PathBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/PathBlackBerry.cpp
new file mode 100644 (file)
index 0000000..ba8ea19
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "Path.h"
+
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "NotImplemented.h"
+#include "StrokeStyleApplier.h"
+
+#include <BlackBerryPlatformGraphics.h>
+#include <BlackBerryPlatformGraphicsContext.h>
+#include <stdio.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+static GraphicsContext* scratchContext()
+{
+    static BlackBerry::Platform::Graphics::Buffer* buffer = BlackBerry::Platform::Graphics::createBuffer(IntSize(), BlackBerry::Platform::Graphics::NeverBacked);
+    static PlatformGraphicsContext* pgc = lockBufferDrawable(buffer);
+    static GraphicsContext gc(pgc);
+    return &gc;
+}
+
+Path::Path() : m_path(new BlackBerry::Platform::Graphics::Path)
+{
+}
+
+Path::Path(const PlatformPath& path)
+    : m_path(new BlackBerry::Platform::Graphics::Path(path))
+{
+}
+
+Path::~Path()
+{
+    if (m_path) {
+        delete m_path;
+        m_path = 0;
+    }
+}
+
+Path::Path(const Path& other)
+{
+    m_path = new BlackBerry::Platform::Graphics::Path(*other.m_path);
+}
+
+Path& Path::operator=(const Path& other)
+{
+    if (m_path) {
+        delete m_path;
+        m_path = 0;
+    }
+    m_path = new BlackBerry::Platform::Graphics::Path(*other.m_path);
+    return *this;
+}
+
+FloatPoint Path::currentPoint() const
+{
+    return m_path->currentPoint();
+}
+
+bool Path::contains(const FloatPoint& point, WindRule rule) const
+{
+    return m_path->contains(point, (BlackBerry::Platform::Graphics::WindRule)(rule));
+}
+
+bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const
+{
+    GraphicsContext* scratch = scratchContext();
+    scratch->save();
+
+    if (applier)
+        applier->strokeStyle(scratch);
+
+    bool result = scratchContext()->platformContext()->strokeContains(*m_path, point);
+    scratch->restore();
+    return result;
+}
+
+void Path::translate(const FloatSize& size)
+{
+    AffineTransform transformation;
+    transformation.translate(size.width(), size.height());
+    transform(transformation);
+}
+
+FloatRect Path::boundingRect() const
+{
+    return m_path->getBounds();
+}
+
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
+{
+    GraphicsContext* scratch = scratchContext();
+    scratch->save();
+
+    if (applier)
+        applier->strokeStyle(scratch);
+
+    FloatRect result = scratch->platformContext()->getStrokeBounds(*m_path);
+
+    scratch->restore();
+    return result;
+}
+
+void Path::moveTo(const FloatPoint& point)
+{
+    m_path->moveTo(point);
+}
+
+void Path::addLineTo(const FloatPoint& point)
+{
+    m_path->addLineTo(point);
+}
+
+void Path::addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint)
+{
+    m_path->addQuadCurveTo(controlPoint, endPoint);
+}
+
+void Path::addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint)
+{
+    m_path->addBezierCurveTo(controlPoint1, controlPoint2, endPoint);
+}
+
+void Path::addArcTo(const FloatPoint& point1, const FloatPoint& point2, float radius)
+{
+    m_path->addArcTo(point1, point2, radius);
+}
+
+void Path::closeSubpath()
+{
+    m_path->closeSubpath();
+}
+
+void Path::addArc(const FloatPoint& center, float radius, float startAngle, float endAngle, bool anticlockwise)
+{
+    m_path->addArc(center, radius, startAngle, endAngle, anticlockwise);
+}
+
+void Path::addRect(const FloatRect& rect)
+{
+    m_path->addRect(rect);
+}
+
+void Path::addEllipse(const FloatRect& rect)
+{
+    m_path->addEllipse(rect);
+}
+
+void Path::platformAddPathForRoundedRect(const FloatRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius)
+{
+    if (rect.isEmpty())
+        return;
+
+    if (rect.width() < topLeftRadius.width() + topRightRadius.width()
+        || rect.width() < bottomLeftRadius.width() + bottomRightRadius.width()
+        || rect.height() < topLeftRadius.height() + bottomLeftRadius.height()
+        || rect.height() < topRightRadius.height() + bottomRightRadius.height()) {
+        // If all the radii cannot be accommodated, return a rect.
+        addRect(rect);
+        return;
+    }
+
+    BlackBerry::Platform::FloatRoundedRect rr(rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+    // Make sure the generic path reflects the contents of the rounded rects
+    m_path->addRoundedRect(rr);
+}
+
+void Path::clear()
+{
+    m_path->reset();
+}
+
+bool Path::isEmpty() const
+{
+    return m_path->isEmpty();
+}
+
+bool Path::hasCurrentPoint() const
+{
+    return m_path->hasCurrentPoint();
+}
+
+void Path::apply(void* info, PathApplierFunction function) const
+{
+    m_path->apply(info, (void*)function);
+}
+
+void Path::transform(const AffineTransform& transformation)
+{
+    m_path->transform(reinterpret_cast<const double*>(&transformation));
+}
+
+void GraphicsContext::fillPath(const Path& path)
+{
+    BlackBerry::Platform::Graphics::Path* pp = path.platformPath();
+    if (!pp->isEmpty()) {
+        BlackBerry::Platform::Graphics::Gradient* platformGradient = fillGradient() ? fillGradient()->platformGradient() : 0;
+        BlackBerry::Platform::Graphics::Pattern* platformPattern = fillPattern() ? fillPattern()->platformPattern(AffineTransform()) : 0;
+        platformContext()->addFillPath(*pp, (BlackBerry::Platform::Graphics::WindRule)m_state.fillRule, platformGradient, platformPattern);
+    }
+}
+
+void GraphicsContext::strokePath(const Path& path)
+{
+    BlackBerry::Platform::Graphics::Path* pp = path.platformPath();
+    if (!pp->isEmpty()) {
+        BlackBerry::Platform::Graphics::Gradient* gradient = strokeGradient() ? strokeGradient()->platformGradient() : 0;
+        BlackBerry::Platform::Graphics::Pattern* pattern = strokePattern() ? strokePattern()->platformPattern(AffineTransform()) : 0;
+        platformContext()->addStrokePath(*pp, gradient, pattern);
+    }
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
+{
+    notImplemented();
+}
+
+void GraphicsContext::drawFocusRing(const Path& path, int width, int offset, const Color& color)
+{
+    notImplemented();
+}
+
+void GraphicsContext::drawLine(const IntPoint& from, const IntPoint& to)
+{
+    platformContext()->addDrawLine(from, to);
+}
+
+void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& pt, float width, DocumentMarkerLineStyle style)
+{
+    platformContext()->addDrawLineForDocumentMarker(pt, width, (BlackBerry::Platform::Graphics::DocumentMarkerLineStyle)style);
+}
+
+void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool printing)
+{
+    platformContext()->addDrawLineForText(pt, width, printing);
+}
+
+void GraphicsContext::clip(const Path& path)
+{
+    BlackBerry::Platform::Graphics::Path* pp = path.platformPath();
+    pp->applyAsClip(platformContext());
+}
+
+void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
+{
+    if (path.platformPath()->isRectangular())
+        platformContext()->clip(path.boundingRect());
+    else
+        clip(path);
+}
+
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
+void GraphicsContext::clipOut(const Path& path)
+{
+    BlackBerry::Platform::Graphics::Path* pp = path.platformPath();
+    pp->applyAsClipOut(platformContext());
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/blackberry/PatternBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/PatternBlackBerry.cpp
new file mode 100644 (file)
index 0000000..d600fcd
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "Pattern.h"
+
+#include "AffineTransform.h"
+#include "Image.h"
+#include "NativeImagePtr.h"
+#include "Path.h"
+
+#include <BlackBerryPlatformGraphicsContext.h>
+
+using namespace std;
+
+namespace WebCore {
+
+void Pattern::platformDestroy()
+{
+    delete m_pattern;
+    m_pattern = 0;
+}
+
+PlatformPatternPtr Pattern::platformPattern(const AffineTransform& patternTransform)
+{
+    if (m_pattern)
+        return m_pattern;
+
+    const NativeImagePtr image = m_tileImage->nativeImageForCurrentFrame();
+
+    m_pattern = BlackBerry::Platform::Graphics::Pattern::create();
+
+    m_pattern->setImage(image, m_repeatX, m_repeatY);
+    m_pattern->setLocalMatrix(reinterpret_cast<const double*>(&m_patternSpaceTransformation));
+
+    return m_pattern;
+}
+
+void Pattern::setPlatformPatternSpaceTransform()
+{
+    if (m_pattern)
+        m_pattern->setLocalMatrix(reinterpret_cast<const double*>(&m_patternSpaceTransformation));
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/blackberry/PlatformSupport.cpp b/Source/WebCore/platform/graphics/blackberry/PlatformSupport.cpp
new file mode 100644 (file)
index 0000000..da59468
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2009-2010, Google Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Research In Motion Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PlatformSupport.h"
+
+#include "FontDescription.h"
+
+#include <fontconfig/fontconfig.h>
+#include <string.h>
+#include <unicode/utf16.h>
+#include <unistd.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+void PlatformSupport::getFontFamilyForCharacters(const UChar* characters, size_t numCharacters, const char*, const FontDescription& description, FontFamily* family)
+{
+    FcCharSet* cset = FcCharSetCreate();
+    for (size_t i = 0; i < numCharacters; ++i) {
+        if (U16_IS_SURROGATE(characters[i])
+            && U16_IS_SURROGATE_LEAD(characters[i])
+            && i != numCharacters - 1
+            && U16_IS_TRAIL(characters[i + 1])) {
+            FcCharSetAddChar(cset, U16_GET_SUPPLEMENTARY(characters[i], characters[i+1]));
+            i++;
+        } else
+            FcCharSetAddChar(cset, characters[i]);
+    }
+    FcPattern* pattern = FcPatternCreate();
+
+    FcValue fcvalue;
+    fcvalue.type = FcTypeCharSet;
+    fcvalue.u.c = cset;
+    FcPatternAdd(pattern, FC_CHARSET, fcvalue, FcFalse);
+
+    fcvalue.type = FcTypeBool;
+    fcvalue.u.b = FcTrue;
+    FcPatternAdd(pattern, FC_SCALABLE, fcvalue, FcFalse);
+
+    fcvalue.type = FcTypeInteger;
+    fcvalue.u.i = (description.weight() >= FontWeightBold) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL;
+    FcPatternAdd(pattern, FC_WEIGHT, fcvalue, FcFalse);
+
+    fcvalue.type = FcTypeInteger;
+    fcvalue.u.i = (description.italic() == FontItalicOn) ? FC_SLANT_ITALIC : FC_SLANT_ROMAN;
+    FcPatternAdd(pattern, FC_SLANT, fcvalue, FcFalse);
+
+    FcConfigSubstitute(0, pattern, FcMatchPattern);
+    FcDefaultSubstitute(pattern);
+
+    FcResult result;
+    FcFontSet* fontSet = FcFontSort(0, pattern, 0, 0, &result);
+    FcPatternDestroy(pattern);
+    FcCharSetDestroy(cset);
+
+    if (!fontSet) {
+        family->name = String();
+        family->isBold = false;
+        family->isItalic = false;
+        return;
+    }
+
+    // Older versions of fontconfig have a bug where they cannot select
+    // only scalable fonts so we have to manually filter the results.
+    for (int i = 0; i < fontSet->nfont; ++i) {
+        FcPattern* current = fontSet->fonts[i];
+        FcBool isScalable;
+
+        if (FcPatternGetBool(current, FC_SCALABLE, 0, &isScalable) != FcResultMatch
+            || !isScalable)
+            continue;
+
+        // fontconfig can also return fonts which are unreadable
+        FcChar8* cFilename;
+        if (FcPatternGetString(current, FC_FILE, 0, &cFilename) != FcResultMatch)
+            continue;
+
+        if (access(reinterpret_cast<char*>(cFilename), R_OK))
+            continue;
+
+        FcChar8* familyName;
+        if (FcPatternGetString(current, FC_FAMILY, 0, &familyName) == FcResultMatch) {
+            const char* charFamily = reinterpret_cast<char*>(familyName);
+            family->name = String::fromUTF8(charFamily, strlen(charFamily));
+        }
+
+        int weight;
+        if (FcPatternGetInteger(current, FC_WEIGHT, 0, &weight) == FcResultMatch)
+            family->isBold = weight >= FC_WEIGHT_BOLD;
+        else
+            family->isBold = false;
+
+        int slant;
+        if (FcPatternGetInteger(current, FC_SLANT, 0, &slant) == FcResultMatch)
+            family->isItalic = slant != FC_SLANT_ROMAN;
+        else
+            family->isItalic = false;
+
+        FcFontSetDestroy(fontSet);
+        return;
+    }
+
+    FcFontSetDestroy(fontSet);
+}
+
+}; // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/blackberry/PlatformSupport.h b/Source/WebCore/platform/graphics/blackberry/PlatformSupport.h
new file mode 100644 (file)
index 0000000..9166ea4
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * Copyright (c) 2011, Research In Motion. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PlatformSupport_h
+#define PlatformSupport_h
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+struct FontRenderStyle;
+class FontDescription;
+
+// This is a minimal version of the Chromium PlatformSupport/WebFontInfo classes used for font support.
+class PlatformSupport {
+public:
+    struct FontFamily {
+        String name;
+        bool isBold;
+        bool isItalic;
+    };
+    static void getFontFamilyForCharacters(const UChar*, size_t numCharacters, const char* preferredLocale, const FontDescription&, FontFamily*);
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/graphics/blackberry/SimpleFontDataBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/SimpleFontDataBlackBerry.cpp
new file mode 100644 (file)
index 0000000..c67009b
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "SimpleFontData.h"
+
+#include "FloatRect.h"
+#include "Font.h"
+#include "FontCache.h"
+#include "FontDescription.h"
+#include "ITypeUtils.h"
+
+#include <fs_api.h>
+#include <unicode/normlzr.h>
+
+namespace WebCore {
+
+// Smallcaps versions of fonts are 70% the size of the normal font.
+static const float smallCapsFraction = 0.7f;
+static const float emphasisMarkFraction = .5;
+
+static inline float FSFixedToFloat(FS_FIXED n) { return n / 65536.0; }
+
+#define openTypeTag(a, b, c, d) (FS_ULONG)((a << 24) | (b << 16) | (c << 8) | d)
+
+void SimpleFontData::platformInit()
+{
+    FS_FIXED ascender = 0;
+    FS_FIXED descender = 0;
+    FS_FIXED leading = 0;
+    FsAscDescLeadSource source;
+    FS_LONG result;
+    if (m_platformData.size() > 0) {
+        // FIXME: hack! FS_get_ascender_descender_leading() returns ERR_NO_CURRENT_SFNT when size is 0, even though we called FS_set_scale and m_platformData.font()->cur_sfnt is not 0
+        result = FS_get_ascender_descender_leading(m_platformData.font(), &ascender, &descender, &leading, &source);
+        ASSERT_UNUSED(result, result == SUCCESS);
+    }
+
+    m_fontMetrics.setAscent(FS_ROUND(ascender));
+    m_fontMetrics.setDescent(FS_ROUND(descender));
+    m_fontMetrics.setLineGap(iTypeFixedToFloat(leading));
+    m_fontMetrics.setLineSpacing(lroundf(m_fontMetrics.ascent()) + lroundf(m_fontMetrics.descent()) + lroundf(m_fontMetrics.lineGap()));
+
+    FONT_METRICS metrics;
+    result = FS_font_metrics(m_platformData.font(), &metrics);
+    ASSERT_UNUSED(result, result == SUCCESS);
+
+    // m_fontMetrics.setUnitsPerEm(FS_get_design_units(m_platformData().font()));
+    m_fontMetrics.setUnitsPerEm(metrics.unitsPerEm);
+
+    FS_USHORT xRange = metrics.font_bbox.xMax - metrics.font_bbox.xMin;
+    m_maxCharWidth = roundf((xRange * roundf(m_platformData.size())) / metrics.unitsPerEm);
+
+    TTF_OS2 os2;
+    if (FS_get_table_structure(m_platformData.font(), TAG_OS2, &os2) == SUCCESS && os2.sxHeight && os2.xAvgCharWidth) {
+        FS_USHORT yppem = m_platformData.font()->lpm;
+        m_fontMetrics.setXHeight(static_cast<float>(os2.sxHeight) * yppem / metrics.unitsPerEm);
+        m_avgCharWidth = static_cast<float>(os2.xAvgCharWidth) * yppem / metrics.unitsPerEm;
+    } else {
+        // HACK
+        m_fontMetrics.setXHeight(m_fontMetrics.ascent() * 0.56);
+        m_fontMetrics.setHasXHeight(false);
+        m_avgCharWidth = m_fontMetrics.xHeight();
+
+        GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
+
+        if (glyphPageZero) {
+            static const UChar32 xChar = 'x';
+            const Glyph xGlyph = glyphPageZero->glyphDataForCharacter(xChar).glyph;
+
+            if (xGlyph) {
+                // In widthForGlyph(), xGlyph will be compared with
+                // m_zeroWidthSpaceGlyph, which isn't initialized yet here.
+                // Initialize it with zero to make sure widthForGlyph() returns
+                // the right width.
+                m_zeroWidthSpaceGlyph = 0;
+                m_avgCharWidth = widthForGlyph(xGlyph);
+            }
+        }
+    }
+
+    if (m_platformData.orientation() == Vertical && !isTextOrientationFallback())
+        m_hasVerticalGlyphs = FS_get_table(m_platformData.font(), openTypeTag('v', 'h', 'e', 'a'), TBL_QUERY, 0)
+            || FS_get_table(m_platformData.font(), openTypeTag('V', 'O', 'R', 'G'), TBL_QUERY, 0);
+}
+
+void SimpleFontData::platformCharWidthInit()
+{
+}
+
+void SimpleFontData::platformDestroy()
+{
+}
+
+PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+{
+    const float scaledSize = lroundf(fontDescription.computedSize() * scaleFactor);
+    return adoptPtr(new SimpleFontData(
+        FontPlatformData(m_platformData.font()->cur_lfnt->name,
+            scaledSize,
+            m_platformData.syntheticBold(),
+            m_platformData.syntheticOblique(),
+            m_platformData.orientation(),
+            m_platformData.textOrientation(),
+            m_platformData.widthVariant()),
+        isCustomFont(), false));
+}
+
+SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFraction);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, emphasisMarkFraction);
+
+    return m_derivedFontData->emphasisMark.get();
+}
+
+bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
+{
+    int position = 0;
+
+    while (position < length) {
+        // FIXME: use shaper?
+        UChar32 character;
+        int nextPosition = position;
+        U16_NEXT(characters, nextPosition, length, character);
+
+        FS_USHORT glyph = FS_map_char(m_platformData.font(), static_cast<FS_ULONG>(character));
+        if (!glyph)
+            return false;
+
+        position = nextPosition;
+    }
+
+    return true;
+}
+
+void SimpleFontData::determinePitch()
+{
+    m_treatAsFixedPitch = m_platformData.isFixedPitch();
+}
+
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
+{
+    FS_GLYPHMAP* glyphmap = FS_get_glyphmap(m_platformData.font(), glyph, FS_MAP_DISTANCEFIELD | FS_MAP_GRAYMAP8);
+    if (!glyphmap)
+        return FloatRect();
+
+    FloatRect bounds(glyphmap->lo_x, glyphmap->height - glyphmap->hi_y, glyphmap->width, glyphmap->height);
+    FS_free_char(m_platformData.font(), glyphmap);
+
+    return bounds;
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
+{
+    FS_SHORT idx, idy;
+    FS_FIXED dx, dy;
+    if (FS_get_advance(m_platformData.font(), glyph, FS_MAP_DISTANCEFIELD | FS_MAP_GRAYMAP8, &idx, &idy, &dx, &dy) != SUCCESS)
+        return 0;
+
+    return iTypeFixedToFloat(dx);
+}
+
+bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters, size_t length) const
+{
+    if (!m_combiningCharacterSequenceSupport)
+        m_combiningCharacterSequenceSupport = adoptPtr(new HashMap<String, bool>);
+
+    WTF::HashMap<String, bool>::AddResult addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false);
+    if (!addResult.isNewEntry)
+        return addResult.iterator->value;
+
+    UErrorCode error = U_ZERO_ERROR;
+    Vector<UChar, 4> normalizedCharacters(length);
+    int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error);
+    if (U_FAILURE(error))
+        return false;
+
+    int position = 0;
+    while (position < normalizedLength) {
+        UChar32 character;
+        int nextPosition = position;
+        U16_NEXT(normalizedCharacters, nextPosition, normalizedLength, character);
+
+        if (!u_hasBinaryProperty(character, UCHAR_DEFAULT_IGNORABLE_CODE_POINT)) {
+            FS_USHORT glyph = FS_map_char(m_platformData.font(), static_cast<FS_ULONG>(character));
+            if (!glyph)
+                return false;
+        }
+
+        position = nextPosition;
+    }
+
+    addResult.iterator->value = true;
+    return true;
+}
+
+} // namespace WebCore