Bug 311378 freeze/hang in several seconds when a character which does not exist in fonts is rendered. patch by Masatoshi Kimura (emk) <VYV03354@nifty.ne.jp> r=timeless, sr=rbs

This commit is contained in:
masayuki%d-toybox.com 2005-12-14 14:51:10 +00:00
Родитель 0a84f833ba
Коммит fe6c972cff
3 изменённых файлов: 88 добавлений и 127 удалений

Просмотреть файл

@ -1307,7 +1307,7 @@ static PRUint8 gBitToUnicodeRange[] =
/* 66 */ kRangeArabic, // fe50 - fe6f Small Form Variants
/* 67 */ kRangeArabic, // fe70 - fefe Arabic Presen. FormsB
/* 68 */ kRangeSetCJK, // ff00 - ffef Half/Fullwidth Forms
/* 69 */ kRangeSetCJK, // fff0 - fffd Specials
/* 69 */ kRangeSpecials, // fff0 - fffd Specials
/* 70 */ kRangeTibetan, // 0f00 - 0fcf Tibetan
/* 71 */ kRangeSyriac, // 0700 - 074f Syriac
/* 72 */ kRangeThaana, // 0780 - 07bf Thaana
@ -2730,6 +2730,9 @@ nsFontMetricsWin::SameAsPreviousMap(int aIndex)
if (tmp->flags & NS_GLOBALFONT_SKIP) {
continue;
}
if (!tmp->ccmap) {
continue;
}
if (tmp->ccmap == font->ccmap) {
font->flags |= NS_GLOBALFONT_SKIP;
return 1;
@ -2744,6 +2747,24 @@ nsFontMetricsWin::SameAsPreviousMap(int aIndex)
return 0;
}
#ifndef WINCE
static
void BitFromUnicodeRange(PRUint32 range, DWORD* usb)
{
for (int i = 0, dword = 0; dword < 3; ++dword) {
for (int bit = 0; bit < sizeof(DWORD) * 8; ++bit, ++i) {
if (range == gBitToUnicodeRange[i]) {
usb[dword] |= 1 << bit;
}
}
}
}
#endif
#ifdef DEBUG_emk
static LARGE_INTEGER freq, prev;
#endif
nsFontWin*
nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUint32 c)
{
@ -2753,6 +2774,12 @@ nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUint32 c)
return nsnull;
}
}
#ifndef WINCE
PRUint32 range = (c <= 0xFFFF) ? FindCharUnicodeRange(c) : kRangeSurrogate;
DWORD usb[4];
memset(usb, 0, sizeof(usb));
BitFromUnicodeRange(range, usb);
#endif
int count = gGlobalFonts->Count();
for (int i = 0; i < count; ++i) {
nsGlobalFont* font = (nsGlobalFont*)gGlobalFonts->ElementAt(i);
@ -2760,6 +2787,15 @@ nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUint32 c)
continue;
}
if (!font->ccmap) {
#ifndef WINCE
// bail out if Unicode range indicates the font have no glyph
if (font->flags & NS_GLOBALFONT_TRUETYPE &&
!(font->signature.fsUsb[0] & usb[0]) &&
!(font->signature.fsUsb[1] & usb[1]) &&
!(font->signature.fsUsb[2] & usb[2])) {
continue;
}
#endif
// don't adjust here, we just want to quickly get the CMAP. Adjusting
// is meant to only happen when loading the final font in LoadFont()
HFONT hfont = ::CreateFontIndirect(&font->logFont);
@ -2775,14 +2811,28 @@ nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUint32 c)
font->flags |= NS_GLOBALFONT_SKIP;
continue;
}
#ifdef DEBUG_emk
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
printf("CCMAP loaded: %g sec, %s [%08X][%08X][%08X]\n", (now.QuadPart - prev.QuadPart) / (double)freq.QuadPart,
font->logFont.lfFaceName, font->signature.fsUsb[0], font->signature.fsUsb[1], font->signature.fsUsb[2]);
prev = now;
#endif
if (SameAsPreviousMap(i)) {
continue;
}
}
if (CCMAP_HAS_CHAR_EXT(font->ccmap, c)) {
#ifdef DEBUG_emk
printf("font found:[%s]\n", font->logFont.lfFaceName);
printf("U+%04X (%d)[%08X][%08X][%08X]\n", c, range, usb[0], usb[1], usb[2]);
#endif
return LoadGlobalFont(aDC, font);
}
}
#ifdef DEBUG_emk
printf("U+%04X (%d)[%08X][%08X][%08X]\n", c, range, usb[0], usb[1], usb[2]);
#endif
return nsnull;
}
@ -3555,6 +3605,11 @@ nsFontMetricsWin::FindPrefFont(HDC aDC, PRUint32 aChar)
nsFontWin*
nsFontMetricsWin::FindFont(HDC aDC, PRUint32 aChar)
{
#ifdef DEBUG_emk
LARGE_INTEGER start, end;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
#endif
// the first font should be for invisible ignorable characters
if (mLoadedFonts.Count() < 1)
mLoadedFonts.AppendElement(gFontForIgnorable);
@ -3569,8 +3624,15 @@ nsFontMetricsWin::FindFont(HDC aDC, PRUint32 aChar)
if (!font) {
font = FindPrefFont(aDC, aChar);
if (!font) {
#ifdef DEBUG_emk
QueryPerformanceCounter(&prev);
#endif
font = FindGlobalFont(aDC, aChar);
if (!font) {
#ifdef DEBUG_emk
QueryPerformanceCounter(&end);
printf("%g sec.\n", (end.QuadPart - start.QuadPart) / (double)freq.QuadPart);
#endif
font = FindSubstituteFont(aDC, aChar);
}
}

Просмотреть файл

@ -206,7 +206,7 @@ const char *gUnicodeRangeToLangGroupTable[] =
#define NUM_OF_SUBTABLES 7
#define NUM_OF_SUBTABLES 8
#define SUBTABLE_SIZE 16
static PRUint8 gUnicodeSubrangeTable[NUM_OF_SUBTABLES][SUBTABLE_SIZE] =
@ -339,8 +339,26 @@ static PRUint8 gUnicodeSubrangeTable[NUM_OF_SUBTABLES][SUBTABLE_SIZE] =
// CJK compatibility forms,
// small form variants
kRangeSetCJK, //uffxx, halfwidth and fullwidth forms, includes Special
}
kRangeTableBase+7, //uffxx, halfwidth and fullwidth forms, includes Special
},
{ //table for 0xff00 - 0xffff
kRangeSetCJK, //uff0x, fullwidth latin
kRangeSetCJK, //uff1x, fullwidth latin
kRangeSetCJK, //uff2x, fullwidth latin
kRangeSetCJK, //uff3x, fullwidth latin
kRangeSetCJK, //uff4x, fullwidth latin
kRangeSetCJK, //uff5x, fullwidth latin
kRangeSetCJK, //uff6x, halfwidth katakana
kRangeSetCJK, //uff7x, halfwidth katakana
kRangeSetCJK, //uff8x, halfwidth katakana
kRangeSetCJK, //uff9x, halfwidth katakana
kRangeSetCJK, //uffax, halfwidth hangul jamo
kRangeSetCJK, //uffbx, halfwidth hangul jamo
kRangeSetCJK, //uffcx, halfwidth hangul jamo
kRangeSetCJK, //uffdx, halfwidth hangul jamo
kRangeSetCJK, //uffex, fullwidth symbols
kRangeSpecials, //ufffx, Specials
},
};
// Most scripts between U+0700 and U+16FF are assigned a chunk of 128 (0x80)
@ -407,9 +425,11 @@ PRUint32 FindCharUnicodeRange(PRUnichar ch)
// otherwise, we have one more table to look at
range = gUnicodeSubrangeTable[range - kRangeTableBase][(ch & 0x0f00) >> 8];
if (range < kRangeTableBase)
return range;
if (range < kRangeTertiaryTable)
return range;
return gUnicodeSubrangeTable[range - kRangeTableBase][(ch & 0x00f0) >> 4];
// Yet another table to look at : U+0700 - U+16FF : 128 code point blocks
return gUnicodeTertiaryRangeTable[(ch - 0x0700) >> 7];
return gUnicodeTertiaryRangeTable[(ch - 0x0700) >> 7];
}

Просмотреть файл

@ -1,121 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nscore.h"
// The following constants define unicode subranges
// values below kRangeNum must be continuous so that we can map to
// lang group directly.
// all ranges we care about should be defined under 32, that allows
// us to store range using bits of a PRUint32
// frequently used range definitions
const PRUint8 kRangeCyrillic = 0;
const PRUint8 kRangeGreek = 1;
const PRUint8 kRangeTurkish = 2;
const PRUint8 kRangeHebrew = 3;
const PRUint8 kRangeArabic = 4;
const PRUint8 kRangeBaltic = 5;
const PRUint8 kRangeThai = 6;
const PRUint8 kRangeKorean = 7;
const PRUint8 kRangeJapanese = 8;
const PRUint8 kRangeSChinese = 9;
const PRUint8 kRangeTChinese = 10;
const PRUint8 kRangeDevanagari = 11;
const PRUint8 kRangeTamil = 12;
const PRUint8 kRangeArmenian = 13;
const PRUint8 kRangeBengali = 14;
const PRUint8 kRangeCanadian = 15;
const PRUint8 kRangeEthiopic = 16;
const PRUint8 kRangeGeorgian = 17;
const PRUint8 kRangeGujarati = 18;
const PRUint8 kRangeGurmukhi = 19;
const PRUint8 kRangeKhmer = 20;
const PRUint8 kRangeMalayalam = 21;
const PRUint8 kRangeSpecificItemNum = 22;
//range/rangeSet grow to this place 22-29
const PRUint8 kRangeSetStart = 30; // range set definition starts from here
const PRUint8 kRangeSetLatin = 30;
const PRUint8 kRangeSetCJK = 31;
const PRUint8 kRangeSetEnd = 31; // range set definition ends here
// less frequently used range definition
const PRUint8 kRangeSurrogate = 32;
const PRUint8 kRangePrivate = 33;
const PRUint8 kRangeMisc = 34;
const PRUint8 kRangeUnassigned = 35;
const PRUint8 kRangeSyriac = 36;
const PRUint8 kRangeThaana = 37;
const PRUint8 kRangeOriya = 38;
const PRUint8 kRangeTelugu = 39;
const PRUint8 kRangeKannada = 40;
const PRUint8 kRangeSinhala = 41;
const PRUint8 kRangeLao = 42;
const PRUint8 kRangeTibetan = 43;
const PRUint8 kRangeMyanmar = 44;
const PRUint8 kRangeCherokee = 45;
const PRUint8 kRangeOghamRunic = 46;
const PRUint8 kRangeMongolian = 47;
const PRUint8 kRangeMathOperators = 48;
const PRUint8 kRangeMiscTechnical = 49;
const PRUint8 kRangeControlOpticalEnclose = 50;
const PRUint8 kRangeBoxBlockGeometrics = 51;
const PRUint8 kRangeMiscSymbols = 52;
const PRUint8 kRangeDingbats = 53;
const PRUint8 kRangeBraillePattern = 54;
const PRUint8 kRangeYi = 55;
const PRUint8 kRangeCombiningDiacriticalMarks = 56;
const PRUint8 kRangeTableBase = 128; //values over 127 are reserved for internal use only
const PRUint8 kRangeTertiaryTable = 145; // leave room for 16 subtable
// indices (kRangeTableBase + 1 ..
// kRangeTableBase + 16)
extern PRUint32 FindCharUnicodeRange(PRUnichar ch);
extern const char* gUnicodeRangeToLangGroupTable[];
inline const char* LangGroupFromUnicodeRange(PRUint8 unicodeRange)
{
if (kRangeSpecificItemNum > unicodeRange)
return gUnicodeRangeToLangGroupTable[unicodeRange];
return nsnull;
}