⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 renderlistmarker.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) * * 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 "RenderListMarker.h"#include "CachedImage.h"#include "CharacterNames.h"#include "Document.h"#include "GraphicsContext.h"#include "ListMarkerBox.h"#include "RenderLayer.h"#include "RenderListItem.h"#include "RenderView.h"using namespace std;using namespace WTF;using namespace Unicode;namespace WebCore {const int cMarkerPadding = 7;static String toRoman(int number, bool upper){    // FIXME: CSS3 describes how to make this work for much larger numbers,    // using overbars and special characters. It also specifies the characters    // in the range U+2160 to U+217F instead of standard ASCII ones.    if (number < 1 || number > 3999)        return String::number(number);    const int lettersSize = 12; // big enough for three each of I, X, C, and M    UChar letters[lettersSize];    int length = 0;    const UChar ldigits[] = { 'i', 'v', 'x', 'l', 'c', 'd', 'm' };    const UChar udigits[] = { 'I', 'V', 'X', 'L', 'C', 'D', 'M' };    const UChar* digits = upper ? udigits : ldigits;    int d = 0;    do {        int num = number % 10;        if (num % 5 < 4)            for (int i = num % 5; i > 0; i--)                letters[lettersSize - ++length] = digits[d];        if (num >= 4 && num <= 8)            letters[lettersSize - ++length] = digits[d + 1];        if (num == 9)            letters[lettersSize - ++length] = digits[d + 2];        if (num % 5 == 4)            letters[lettersSize - ++length] = digits[d];        number /= 10;        d += 2;    } while (number);    ASSERT(length <= lettersSize);    return String(&letters[lettersSize - length], length);}static String toAlphabetic(int number, const UChar* alphabet, int alphabetSize){    ASSERT(alphabetSize >= 10);    if (number < 1)        return String::number(number);    const int lettersSize = 10; // big enough for a 32-bit int, with a 10-letter alphabet    UChar letters[lettersSize];    --number;    letters[lettersSize - 1] = alphabet[number % alphabetSize];    int length = 1;    while ((number /= alphabetSize) > 0)        letters[lettersSize - ++length] = alphabet[number % alphabetSize - 1];    ASSERT(length <= lettersSize);    return String(&letters[lettersSize - length], length);}static int toHebrewUnder1000(int number, UChar letters[5]){    // FIXME: CSS3 mentions various refinements not implemented here.    // FIXME: Should take a look at Mozilla's HebrewToText function (in nsBulletFrame).    ASSERT(number >= 0 && number < 1000);    int length = 0;    int fourHundreds = number / 400;    for (int i = 0; i < fourHundreds; i++)        letters[length++] = 1511 + 3;    number %= 400;    if (number / 100)        letters[length++] = 1511 + (number / 100) - 1;    number %= 100;    if (number == 15 || number == 16) {        letters[length++] = 1487 + 9;        letters[length++] = 1487 + number - 9;    } else {        if (int tens = number / 10) {            static const UChar hebrewTens[9] = { 1497, 1499, 1500, 1502, 1504, 1505, 1506, 1508, 1510 };            letters[length++] = hebrewTens[tens - 1];        }        if (int ones = number % 10)            letters[length++] = 1487 + ones;    }    ASSERT(length <= 5);    return length;}static String toHebrew(int number){    // FIXME: CSS3 mentions ways to make this work for much larger numbers.    if (number < 0 || number > 999999)        return String::number(number);    if (number == 0) {        static const UChar hebrewZero[3] = { 0x05D0, 0x05E4, 0x05E1 };        return String(hebrewZero, 3);    }    const int lettersSize = 11; // big enough for two 5-digit sequences plus a quote mark between    UChar letters[lettersSize];    int length;    if (number < 1000)        length = 0;    else {        length = toHebrewUnder1000(number / 1000, letters);        letters[length++] = '\'';        number = number % 1000;    }    length += toHebrewUnder1000(number, letters + length);    ASSERT(length <= lettersSize);    return String(letters, length);}static int toArmenianUnder10000(int number, bool upper, bool addCircumflex, UChar letters[9]){    ASSERT(number >= 0 && number < 10000);    int length = 0;    int lowerOffset = upper ? 0 : 0x0030;    if (int thousands = number / 1000)        if (thousands == 7) {            letters[length++] = 0x0548 + lowerOffset;            letters[length++] = 0x0552 + lowerOffset;            if (addCircumflex)                letters[length++] = 0x0302;        } else {            letters[length++] = (0x054C - 1 + lowerOffset) + thousands;            if (addCircumflex)                letters[length++] = 0x0302;        }    if (int hundreds = (number / 100) % 10) {        letters[length++] = (0x0543 - 1 + lowerOffset) + hundreds;        if (addCircumflex)            letters[length++] = 0x0302;    }    if (int tens = (number / 10) % 10) {        letters[length++] = (0x053A - 1 + lowerOffset) + tens;        if (addCircumflex)            letters[length++] = 0x0302;    }    if (int ones = number % 10) {        letters[length++] = (0x531 - 1 + lowerOffset) + ones;        if (addCircumflex)            letters[length++] = 0x0302;    }    return length;}static String toArmenian(int number, bool upper){    if (number < 1 || number > 99999999)        return String::number(number);    const int lettersSize = 18; // twice what toArmenianUnder10000 needs    UChar letters[lettersSize];    int length = toArmenianUnder10000(number / 10000, upper, true, letters);    length += toArmenianUnder10000(number % 10000, upper, false, letters + length);    ASSERT(length <= lettersSize);    return String(letters, length);}static String toGeorgian(int number){    if (number < 1 || number > 19999)        return String::number(number);    const int lettersSize = 5;    UChar letters[lettersSize];    int length = 0;    if (number > 9999)        letters[length++] = 0x10F5;    if (int thousands = (number / 1000) % 10) {        static const UChar georgianThousands[9] = {            0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10F4, 0x10EF, 0x10F0        };        letters[length++] = georgianThousands[thousands - 1];    }    if (int hundreds = (number / 100) % 10) {        static const UChar georgianHundreds[9] = {            0x10E0, 0x10E1, 0x10E2, 0x10F3, 0x10E4, 0x10E5, 0x10E6, 0x10E7, 0x10E8        };        letters[length++] = georgianHundreds[hundreds - 1];    }    if (int tens = (number / 10) % 10) {        static const UChar georgianTens[9] = {            0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10F2, 0x10DD, 0x10DE, 0x10DF        };        letters[length++] = georgianTens[tens - 1];    }    if (int ones = number % 10) {        static const UChar georgianOnes[9] = {            0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10F1, 0x10D7        };        letters[length++] = georgianOnes[ones - 1];    }    ASSERT(length <= lettersSize);    return String(letters, length);}// The table uses the order from the CSS3 specification:// first 3 group markers, then 3 digit markers, then ten digits.static String toCJKIdeographic(int number, const UChar table[16]){    if (number < 0)        return String::number(number);    enum AbstractCJKChar {        noChar,        secondGroupMarker, thirdGroupMarker, fourthGroupMarker,        secondDigitMarker, thirdDigitMarker, fourthDigitMarker,        digit0, digit1, digit2, digit3, digit4,        digit5, digit6, digit7, digit8, digit9    };    if (number == 0)        return String(&table[digit0 - 1], 1);    const int groupLength = 8; // 4 digits, 3 digit markers, and a group marker    const int bufferLength = 4 * groupLength;    AbstractCJKChar buffer[bufferLength] = { noChar };    for (int i = 0; i < 4; ++i) {        int groupValue = number % 10000;        number /= 10000;        // Process least-significant group first, but put it in the buffer last.        AbstractCJKChar* group = &buffer[(3 - i) * groupLength];        if (groupValue && i)            group[7] = static_cast<AbstractCJKChar>(secondGroupMarker - 1 + i);        // Put in the four digits and digit markers for any non-zero digits.        group[6] = static_cast<AbstractCJKChar>(digit0 + (groupValue % 10));        if (number != 0 || groupValue > 9) {            int digitValue = ((groupValue / 10) % 10);            group[4] = static_cast<AbstractCJKChar>(digit0 + digitValue);            if (digitValue)                group[5] = secondDigitMarker;        }        if (number != 0 || groupValue > 99) {            int digitValue = ((groupValue / 100) % 10);            group[2] = static_cast<AbstractCJKChar>(digit0 + digitValue);            if (digitValue)                group[3] = thirdDigitMarker;        }        if (number != 0 || groupValue > 999) {            int digitValue = groupValue / 1000;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -