зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
0a84f833ba
Коммит
fe6c972cff
|
@ -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;
|
||||
}
|
Загрузка…
Ссылка в новой задаче