10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/*
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2007-2009 Torch Mobile, Inc.
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2008 Holger Hans Peter Freyther
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Redistribution and use in source and binary forms, with or without
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * modification, are permitted provided that the following conditions
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * are met:
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 1. Redistributions of source code must retain the above copyright
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer.
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    documentation and/or other materials provided with the distribution.
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "config.h"
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Font.h"
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "AffineTransform.h"
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FloatRect.h"
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FontCache.h"
350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FontData.h"
360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FontFallbackList.h"
370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "GlyphBuffer.h"
380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "GraphicsContext.h"
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "IntRect.h"
400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "NotImplemented.h"
41ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h"
420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "WidthIterator.h"
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/MathExtras.h>
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/OwnPtr.h>
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/unicode/Unicode.h>
460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <windows.h>
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochusing namespace WTF::Unicode;
500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace WebCore {
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochHDC g_screenDC = GetDC(0);
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochclass ScreenDcReleaser {
560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochpublic:
570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ~ScreenDcReleaser()
580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ReleaseDC(0, g_screenDC);
600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch};
620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochScreenDcReleaser releaseScreenDc;
640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer,
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                      int from, int numGlyphs, const FloatPoint& point) const
670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    graphicsContext->drawText(fontData, glyphBuffer, from, numGlyphs, point);
690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochclass TextRunComponent {
720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochpublic:
730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    TextRunComponent() : m_textRun(0, 0) {}
740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    TextRunComponent(const UChar *start, int length, const TextRun& parentTextRun, const Font &font, int offset);
750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    TextRunComponent(int spaces, const Font &font, int offset);
760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ~TextRunComponent() { m_textRun; }
770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    bool isSpace() const { return m_spaces; }
790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int textLength() const { return m_spaces ? m_spaces : m_textRun.length(); }
800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    TextRun m_textRun;
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float m_width;
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int m_offset;
840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int m_spaces;
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch};
860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochTextRunComponent::TextRunComponent(const UChar *start, int length, const TextRun& parentTextRun, const Font &font, int o)
880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    : m_textRun(start, length, parentTextRun.allowTabs(), 0, 0
892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        , parentTextRun.allowsTrailingExpansion() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion
900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        , parentTextRun.rtl()
9181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        , parentTextRun.directionalOverride())
920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_offset(o)
930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_spaces(0)
940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    WidthIterator it(&font, m_textRun);
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    it.advance(m_textRun.length(), 0);
970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_width = it.m_runWidthSoFar;
980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochTextRunComponent::TextRunComponent(int s, const Font &font, int o)
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    : m_textRun(0, 0)
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_offset(o)
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_spaces(s)
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_width = s * font.primaryFont()->widthForGlyph(' ');
1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochtypedef Vector<TextRunComponent, 128> TextRunComponents;
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic int generateComponents(TextRunComponents* components, const Font &font, const TextRun &run)
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int letterSpacing = font.letterSpacing();
1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int wordSpacing = font.wordSpacing();
1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    int padding = run.expansion();
1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int numSpaces = 0;
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (padding) {
1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        for (int i = 0; i < run.length(); i++)
1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (Font::treatAsSpace(run[i]))
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                ++numSpaces;
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int offset = 0;
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (letterSpacing) {
1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // need to draw every letter on it's own
1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int start = 0;
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (Font::treatAsSpace(run[0])) {
1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            int add = 0;
1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (numSpaces) {
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                add = padding/numSpaces;
1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                padding -= add;
1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                --numSpaces;
1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            components->append(TextRunComponent(1, font, offset));
1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            offset += add + letterSpacing + components->last().m_width;
1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            start = 1;
1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        for (int i = 1; i < run.length(); ++i) {
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            uint ch = run[i];
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (isHighSurrogate(ch) && isLowSurrogate(run[i-1]))
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                ch = surrogateToUcs4(ch, run[i-1]);
1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (isLowSurrogate(ch) || category(ch) == Mark_NonSpacing)
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                continue;
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (Font::treatAsSpace(run[i])) {
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                int add = 0;
1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (i - start > 0) {
1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    components->append(TextRunComponent(run.characters() + start, i - start,
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                        run, font, offset));
1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    offset += components->last().m_width + letterSpacing;
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                }
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (numSpaces) {
1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    add = padding/numSpaces;
1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    padding -= add;
1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    --numSpaces;
1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                }
1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                components->append(TextRunComponent(1, font, offset));
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                offset += wordSpacing + add + components->last().m_width + letterSpacing;
1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                start = i + 1;
1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                continue;
1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (i - start > 0) {
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                components->append(TextRunComponent(run.characters() + start, i - start,
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                    run,
1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                    font, offset));
1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                offset += components->last().m_width + letterSpacing;
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            start = i;
1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (run.length() - start > 0) {
1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            components->append(TextRunComponent(run.characters() + start, run.length() - start,
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                run,
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                font, offset));
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            offset += components->last().m_width;
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        offset += letterSpacing;
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int start = 0;
1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        for (int i = 0; i < run.length(); ++i) {
1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (Font::treatAsSpace(run[i])) {
1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (i - start > 0) {
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    components->append(TextRunComponent(run.characters() + start, i - start,
1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                        run,
1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                        font, offset));
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    offset += components->last().m_width;
1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                }
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                int add = 0;
1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (numSpaces) {
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    add = padding/numSpaces;
1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    padding -= add;
1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    --numSpaces;
1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                }
1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                components->append(TextRunComponent(1, font, offset));
1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                offset += add + components->last().m_width;
1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (i)
1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    offset += wordSpacing;
1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                start = i + 1;
1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (run.length() - start > 0) {
1990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            components->append(TextRunComponent(run.characters() + start, run.length() - start,
2000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                run,
2010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                font, offset));
2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            offset += components->last().m_width;
2030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return offset;
2060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
2090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                           int from, int to) const
2100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (to < 0)
2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        to = run.length();
2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (from < 0)
2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        from = 0;
2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    TextRunComponents components;
2170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int w = generateComponents(&components, *this, run);
2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int curPos = 0;
2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    for (int i = 0; i < (int)components.size(); ++i) {
2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        const TextRunComponent& comp = components.at(i);
2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int len = comp.textLength();
2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int curEnd = curPos + len;
2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (curPos < to && from < curEnd && !comp.isSpace()) {
2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            FloatPoint pt = point;
2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (run.rtl())
2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                pt.setX(point.x() + w - comp.m_offset - comp.m_width);
2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            else
2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                pt.setX(point.x() + comp.m_offset);
2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            drawSimpleText(context, comp.m_textRun, pt, from - curPos, std::min(to, curEnd) - curPos);
2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        curPos += len;
2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (from < curPos)
2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            from = curPos;
2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
238f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
239f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
240f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    notImplemented();
241f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
242f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
243dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfloat Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
2440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    TextRunComponents components;
2460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int w = generateComponents(&components, *this, run);
2470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return w;
2480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
25006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenint Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, bool includePartialGlyphs) const
2510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
25206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // FIXME: This truncation is not a problem for HTML, but only affects SVG, which passes floating-point numbers
25306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // to Font::offsetForPosition(). Bug http://webkit.org/b/40673 tracks fixing this problem.
25406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    int position = static_cast<int>(xFloat);
25506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    TextRunComponents components;
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int w = generateComponents(&components, *this, run);
2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (position >= w)
2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return run.length();
2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int offset = 0;
2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (run.rtl()) {
2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        for (size_t i = 0; i < components.size(); ++i) {
2650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            const TextRunComponent& comp = components.at(i);
2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            int xe = w - comp.m_offset;
2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            int xs = xe - comp.m_width;
2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (position >= xs)
2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                return offset + (comp.isSpace()
2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    ? static_cast<int>((position - xe) * comp.m_spaces / std::max(1.f, comp.m_width) + 0.5)
2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    : offsetForPositionForSimpleText(comp.m_textRun, position - xs, includePartialGlyphs));
2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            offset += comp.textLength();
2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
2760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        for (size_t i = 0; i < components.size(); ++i) {
2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            const TextRunComponent& comp = components.at(i);
2780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            int xs = comp.m_offset;
2790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            int xe = xs + comp.m_width;
2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (position <= xe) {
2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (position - xs >= xe)
2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    return offset + comp.textLength();
2830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                return offset + (comp.isSpace()
2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    ? static_cast<int>((position - xs) * comp.m_spaces / std::max(1.f, comp.m_width) + 0.5)
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    : offsetForPositionForSimpleText(comp.m_textRun, position - xs, includePartialGlyphs));
2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            offset += comp.textLength();
2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return run.length();
2910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic float cursorToX(const Font* font, const TextRunComponents& components, int width, bool rtl, int cursor)
2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int start = 0;
2970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    for (size_t i = 0; i < components.size(); ++i) {
2980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        const TextRunComponent& comp = components.at(i);
2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (start + comp.textLength() <= cursor) {
3000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            start += comp.textLength();
3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            continue;
3020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int xs = comp.m_offset;
3040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (rtl)
3050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            xs = width - xs - comp.m_width;
3060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int pos = cursor - start;
3080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (comp.isSpace()) {
3090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (rtl)
3100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                pos = comp.textLength() - pos;
3110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return xs + pos * comp.m_width / comp.m_spaces;
3120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        WidthIterator it(font, comp.m_textRun);
3140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        it.advance(pos);
3150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return xs + it.m_runWidthSoFar;
3160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
3170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return width;
3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
32006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenFloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& pt,
3210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                     int h, int from, int to) const
3220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    TextRunComponents components;
3240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int w = generateComponents(&components, *this, run);
3250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!from && to == run.length())
3270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return FloatRect(pt.x(), pt.y(), w, h);
3280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float x1 = cursorToX(this, components, w, run.rtl(), from);
3300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float x2 = cursorToX(this, components, w, run.rtl(), to);
3310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (x2 < x1)
3320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        std::swap(x1, x2);
3330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return FloatRect(pt.x() + x1, pt.y(), x2 - x1, h);
3350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool Font::canReturnFallbackFontsForComplexText()
3380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return false;
3400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
3410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3422fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockbool Font::canExpandAroundIdeographsInComplexText()
3432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
3442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return false;
3452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
3462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
34768513a70bcd92384395513322f1b801e7bf9c729Steve Block} // namespace WebCore
348