summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/platform/graphics/wince/FontWince.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/platform/graphics/wince/FontWince.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/wince/FontWince.cpp333
1 files changed, 333 insertions, 0 deletions
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/wince/FontWince.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/wince/FontWince.cpp
new file mode 100644
index 0000000..d00336b
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/wince/FontWince.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Holger Hans Peter Freyther
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "Font.h"
+
+#include "FloatRect.h"
+#include "FontCache.h"
+#include "FontData.h"
+#include "FontFallbackList.h"
+#include "GlyphBuffer.h"
+#include "GraphicsContext.h"
+#include "IntRect.h"
+#include "NotImplemented.h"
+#include "TransformationMatrix.h"
+#include "WidthIterator.h"
+#include <wtf/MathExtras.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/unicode/Unicode.h>
+
+#include <windows.h>
+
+using namespace WTF::Unicode;
+
+namespace WebCore {
+
+HDC g_screenDC = GetDC(0);
+
+class ScreenDcReleaser {
+public:
+ ~ScreenDcReleaser()
+ {
+ ReleaseDC(0, g_screenDC);
+ }
+};
+
+ScreenDcReleaser releaseScreenDc;
+
+void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer,
+ int from, int numGlyphs, const FloatPoint& point) const
+{
+ graphicsContext->drawText(fontData, glyphBuffer, from, numGlyphs, point);
+}
+
+class TextRunComponent {
+public:
+ TextRunComponent() : m_textRun(0, 0) {}
+ TextRunComponent(const UChar *start, int length, const TextRun& parentTextRun, const Font &font, int offset);
+ TextRunComponent(int spaces, const Font &font, int offset);
+ ~TextRunComponent() { m_textRun; }
+
+ bool isSpace() const { return m_spaces; }
+ int textLength() const { return m_spaces ? m_spaces : m_textRun.length(); }
+
+ TextRun m_textRun;
+ float m_width;
+ int m_offset;
+ int m_spaces;
+};
+
+TextRunComponent::TextRunComponent(const UChar *start, int length, const TextRun& parentTextRun, const Font &font, int o)
+ : m_textRun(start, length, parentTextRun.allowTabs(), 0, 0
+ , parentTextRun.rtl()
+ , parentTextRun.directionalOverride()
+ , parentTextRun.applyRunRounding()
+ , parentTextRun.applyWordRounding())
+ , m_offset(o)
+ , m_spaces(0)
+{
+ WidthIterator it(&font, m_textRun);
+ it.advance(m_textRun.length(), 0);
+ m_width = it.m_runWidthSoFar;
+}
+
+TextRunComponent::TextRunComponent(int s, const Font &font, int o)
+ : m_textRun(0, 0)
+ , m_offset(o)
+ , m_spaces(s)
+{
+ m_width = s * font.primaryFont()->widthForGlyph(' ');
+}
+
+typedef Vector<TextRunComponent, 128> TextRunComponents;
+
+static int generateComponents(TextRunComponents* components, const Font &font, const TextRun &run)
+{
+ int letterSpacing = font.letterSpacing();
+ int wordSpacing = font.wordSpacing();
+ int padding = run.padding();
+ int numSpaces = 0;
+ if (padding) {
+ for (int i = 0; i < run.length(); i++)
+ if (Font::treatAsSpace(run[i]))
+ ++numSpaces;
+ }
+
+ int offset = 0;
+ if (letterSpacing) {
+ // need to draw every letter on it's own
+ int start = 0;
+ if (Font::treatAsSpace(run[0])) {
+ int add = 0;
+ if (numSpaces) {
+ add = padding/numSpaces;
+ padding -= add;
+ --numSpaces;
+ }
+ components->append(TextRunComponent(1, font, offset));
+ offset += add + letterSpacing + components->last().m_width;
+ start = 1;
+ }
+ for (int i = 1; i < run.length(); ++i) {
+ uint ch = run[i];
+ if (isHighSurrogate(ch) && isLowSurrogate(run[i-1]))
+ ch = surrogateToUcs4(ch, run[i-1]);
+ if (isLowSurrogate(ch) || category(ch) == Mark_NonSpacing)
+ continue;
+ if (Font::treatAsSpace(run[i])) {
+ int add = 0;
+ if (i - start > 0) {
+ components->append(TextRunComponent(run.characters() + start, i - start,
+ run, font, offset));
+ offset += components->last().m_width + letterSpacing;
+ }
+ if (numSpaces) {
+ add = padding/numSpaces;
+ padding -= add;
+ --numSpaces;
+ }
+ components->append(TextRunComponent(1, font, offset));
+ offset += wordSpacing + add + components->last().m_width + letterSpacing;
+ start = i + 1;
+ continue;
+ }
+ if (i - start > 0) {
+ components->append(TextRunComponent(run.characters() + start, i - start,
+ run,
+ font, offset));
+ offset += components->last().m_width + letterSpacing;
+ }
+ start = i;
+ }
+ if (run.length() - start > 0) {
+ components->append(TextRunComponent(run.characters() + start, run.length() - start,
+ run,
+ font, offset));
+ offset += components->last().m_width;
+ }
+ offset += letterSpacing;
+ } else {
+ int start = 0;
+ for (int i = 0; i < run.length(); ++i) {
+ if (Font::treatAsSpace(run[i])) {
+ if (i - start > 0) {
+ components->append(TextRunComponent(run.characters() + start, i - start,
+ run,
+ font, offset));
+ offset += components->last().m_width;
+ }
+ int add = 0;
+ if (numSpaces) {
+ add = padding/numSpaces;
+ padding -= add;
+ --numSpaces;
+ }
+ components->append(TextRunComponent(1, font, offset));
+ offset += add + components->last().m_width;
+ if (i)
+ offset += wordSpacing;
+ start = i + 1;
+ }
+ }
+ if (run.length() - start > 0) {
+ components->append(TextRunComponent(run.characters() + start, run.length() - start,
+ run,
+ font, offset));
+ offset += components->last().m_width;
+ }
+ }
+ return offset;
+}
+
+void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
+ int from, int to) const
+{
+ if (to < 0)
+ to = run.length();
+ if (from < 0)
+ from = 0;
+
+ TextRunComponents components;
+ int w = generateComponents(&components, *this, run);
+
+ int curPos = 0;
+ for (int i = 0; i < (int)components.size(); ++i) {
+ const TextRunComponent& comp = components.at(i);
+ int len = comp.textLength();
+ int curEnd = curPos + len;
+ if (curPos < to && from < curEnd && !comp.isSpace()) {
+ FloatPoint pt = point;
+ if (run.rtl())
+ pt.setX(point.x() + w - comp.m_offset - comp.m_width);
+ else
+ pt.setX(point.x() + comp.m_offset);
+ drawSimpleText(context, comp.m_textRun, pt, from - curPos, std::min(to, curEnd) - curPos);
+ }
+ curPos += len;
+ if (from < curPos)
+ from = curPos;
+ }
+}
+
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const
+{
+ TextRunComponents components;
+ int w = generateComponents(&components, *this, run);
+ return w;
+}
+
+int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool includePartialGlyphs) const
+{
+ TextRunComponents components;
+ int w = generateComponents(&components, *this, run);
+
+ if (position >= w)
+ return run.length();
+
+ int offset = 0;
+ if (run.rtl()) {
+ for (size_t i = 0; i < components.size(); ++i) {
+ const TextRunComponent& comp = components.at(i);
+ int xe = w - comp.m_offset;
+ int xs = xe - comp.m_width;
+ if (position >= xs)
+ return offset + (comp.isSpace()
+ ? static_cast<int>((position - xe) * comp.m_spaces / std::max(1.f, comp.m_width) + 0.5)
+ : offsetForPositionForSimpleText(comp.m_textRun, position - xs, includePartialGlyphs));
+
+ offset += comp.textLength();
+ }
+ } else {
+ for (size_t i = 0; i < components.size(); ++i) {
+ const TextRunComponent& comp = components.at(i);
+ int xs = comp.m_offset;
+ int xe = xs + comp.m_width;
+ if (position <= xe) {
+ if (position - xs >= xe)
+ return offset + comp.textLength();
+ return offset + (comp.isSpace()
+ ? static_cast<int>((position - xs) * comp.m_spaces / std::max(1.f, comp.m_width) + 0.5)
+ : offsetForPositionForSimpleText(comp.m_textRun, position - xs, includePartialGlyphs));
+ }
+ offset += comp.textLength();
+ }
+ }
+ return run.length();
+}
+
+
+static float cursorToX(const Font* font, const TextRunComponents& components, int width, bool rtl, int cursor)
+{
+ int start = 0;
+ for (size_t i = 0; i < components.size(); ++i) {
+ const TextRunComponent& comp = components.at(i);
+ if (start + comp.textLength() <= cursor) {
+ start += comp.textLength();
+ continue;
+ }
+ int xs = comp.m_offset;
+ if (rtl)
+ xs = width - xs - comp.m_width;
+
+ int pos = cursor - start;
+ if (comp.isSpace()) {
+ if (rtl)
+ pos = comp.textLength() - pos;
+ return xs + pos * comp.m_width / comp.m_spaces;
+ }
+ WidthIterator it(font, comp.m_textRun);
+ it.advance(pos);
+ return xs + it.m_runWidthSoFar;
+ }
+ return width;
+}
+
+FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& pt,
+ int h, int from, int to) const
+{
+ TextRunComponents components;
+ int w = generateComponents(&components, *this, run);
+
+ if (!from && to == run.length())
+ return FloatRect(pt.x(), pt.y(), w, h);
+
+ float x1 = cursorToX(this, components, w, run.rtl(), from);
+ float x2 = cursorToX(this, components, w, run.rtl(), to);
+ if (x2 < x1)
+ std::swap(x1, x2);
+
+ return FloatRect(pt.x() + x1, pt.y(), x2 - x1, h);
+}
+
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return false;
+}
+
+}