diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/platform/graphics/wince/FontWince.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/platform/graphics/wince/FontWince.cpp | 333 |
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; +} + +} |