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