зеркало из https://github.com/mozilla/pjs.git
bug 205387: exclude truly invisible characters from DrawString. The first in a series, fix for GFX:Win (r=smontagu, sr=rbs)
This commit is contained in:
Родитель
3b6cdc2e8c
Коммит
d505eee43e
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -161,6 +161,19 @@ static int gInitialized = 0;
|
|||
static PRBool gDoingLineheightFixup = PR_FALSE;
|
||||
static PRUint16* gUserDefinedCCMap = nsnull;
|
||||
|
||||
// 'virtual' font to 'absorb' truly invisible characters (a subset of
|
||||
// default_ignorable_codepoints listed in
|
||||
// http://www.unicode.org/Public/UNIDATA/DerivedCoreProperties.txt)
|
||||
// and turn them to nothingness.
|
||||
static nsFontWin* gFontForIgnorable = nsnull;
|
||||
static PRUint16 gIgnorableCCMapExtRaw[] = {
|
||||
#include "ignorable.x-ccmap"
|
||||
};
|
||||
|
||||
// It's a pre-compiled extended ccmap so that the pointer
|
||||
// has to point at the 3rd element.
|
||||
static PRUint16 *gIgnorableCCMapExt = gIgnorableCCMapExtRaw + 2;
|
||||
|
||||
static nsCharsetInfo gCharsetInfo[eCharset_COUNT] =
|
||||
{
|
||||
{ "DEFAULT", 0, "", GenerateDefault, nsnull},
|
||||
|
@ -220,6 +233,11 @@ FreeGlobals(void)
|
|||
nsFontMetricsWin::gGlobalFonts = nsnull;
|
||||
}
|
||||
|
||||
if (gFontForIgnorable) {
|
||||
delete gFontForIgnorable;
|
||||
gFontForIgnorable = nsnull;
|
||||
}
|
||||
|
||||
// free FamilyNames
|
||||
if (nsFontMetricsWin::gFamilyNames) {
|
||||
PL_HashTableDestroy(nsFontMetricsWin::gFamilyNames);
|
||||
|
@ -345,6 +363,12 @@ InitGlobals(void)
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
gFontForIgnorable = new nsFontWinSubstitute(gIgnorableCCMapExt);
|
||||
if (!gFontForIgnorable) {
|
||||
FreeGlobals();
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
//register an observer to take care of cleanup
|
||||
gFontCleanupObserver = new nsFontCleanupObserver();
|
||||
NS_ASSERTION(gFontCleanupObserver, "failed to create observer");
|
||||
|
@ -390,7 +414,8 @@ nsFontMetricsWin::~nsFontMetricsWin()
|
|||
mSubstituteFont = nsnull; // released below
|
||||
mFontHandle = nsnull; // released below
|
||||
|
||||
for (PRInt32 i = mLoadedFonts.Count()-1; i >= 0; --i) {
|
||||
// mLoadedFont[0] is gFontForIgnorable that will be deleted in FreeGlobal
|
||||
for (PRInt32 i = mLoadedFonts.Count()-1; i > 0; --i) {
|
||||
delete (nsFontWin*)mLoadedFonts[i];
|
||||
}
|
||||
mLoadedFonts.Clear();
|
||||
|
@ -3467,6 +3492,12 @@ nsFontMetricsWin::FindPrefFont(HDC aDC, PRUint32 aChar)
|
|||
nsFontWin*
|
||||
nsFontMetricsWin::FindFont(HDC aDC, PRUint32 aChar)
|
||||
{
|
||||
// the first font should be for invisible ignorable characters
|
||||
if (mLoadedFonts.Count() < 1)
|
||||
mLoadedFonts.AppendElement(gFontForIgnorable);
|
||||
if (gFontForIgnorable->HasGlyph(aChar))
|
||||
return gFontForIgnorable;
|
||||
|
||||
nsFontWin* font = FindUserDefinedFont(aDC, aChar);
|
||||
if (!font) {
|
||||
font = FindLocalFont(aDC, aChar);
|
||||
|
@ -3900,8 +3931,13 @@ nsFontMetricsWin::ResolveForwards(HDC aDC,
|
|||
|
||||
//This if block is meant to speedup the process in normal situation, when
|
||||
//most characters can be found in first font
|
||||
if (currFont == mLoadedFonts[0]) {
|
||||
while (currChar < lastChar && (currFont->HasGlyph(*currChar)))
|
||||
NS_ASSERTION(count > 1, "only one font loaded");
|
||||
// mLoadedFont[0] == font for invisible ignorable characters
|
||||
PRUint32 firstFont = count > 1 ? 1 : 0;
|
||||
if (currFont == mLoadedFonts[firstFont]) {
|
||||
while (currChar < lastChar &&
|
||||
(currFont->HasGlyph(*currChar)) &&
|
||||
!CCMAP_HAS_CHAR_EXT(gIgnorableCCMapExt, *currChar))
|
||||
++currChar;
|
||||
fontSwitch.mFontWin = currFont;
|
||||
if (!(*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData))
|
||||
|
@ -4286,6 +4322,15 @@ nsFontWinSubstitute::nsFontWinSubstitute(LOGFONT* aLogFont, HFONT aFont,
|
|||
PRUint16* aCCMap, PRBool aDisplayUnicode) : nsFontWin(aLogFont, aFont, aCCMap)
|
||||
{
|
||||
mDisplayUnicode = aDisplayUnicode;
|
||||
mIsForIgnorable = PR_FALSE;
|
||||
memset(mRepresentableCharMap, 0, sizeof(mRepresentableCharMap));
|
||||
}
|
||||
|
||||
nsFontWinSubstitute::nsFontWinSubstitute(PRUint16 *aCCMap) :
|
||||
nsFontWin(NULL, NULL, aCCMap)
|
||||
{
|
||||
mIsForIgnorable = PR_TRUE;
|
||||
mDisplayUnicode = PR_FALSE;
|
||||
memset(mRepresentableCharMap, 0, sizeof(mRepresentableCharMap));
|
||||
}
|
||||
|
||||
|
@ -4359,6 +4404,8 @@ PRInt32
|
|||
nsFontWinSubstitute::GetWidth(HDC aDC, const PRUnichar* aString,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
if (mIsForIgnorable)
|
||||
return 0;
|
||||
nsAutoChar16Buffer buffer;
|
||||
nsresult rv = SubstituteChars(PR_FALSE, aString, aLength, buffer, &aLength);
|
||||
if (NS_FAILED(rv) || !aLength) return 0;
|
||||
|
@ -4374,6 +4421,8 @@ void
|
|||
nsFontWinSubstitute::DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
|
||||
const PRUnichar* aString, PRUint32 aLength)
|
||||
{
|
||||
if (mIsForIgnorable)
|
||||
return;
|
||||
nsAutoChar16Buffer buffer;
|
||||
nsresult rv = SubstituteChars(PR_FALSE, aString, aLength, buffer, &aLength);
|
||||
if (NS_FAILED(rv) || !aLength) return;
|
||||
|
@ -4389,6 +4438,8 @@ nsFontWinSubstitute::GetBoundingMetrics(HDC aDC,
|
|||
nsBoundingMetrics& aBoundingMetrics)
|
||||
{
|
||||
aBoundingMetrics.Clear();
|
||||
if (mIsForIgnorable)
|
||||
return NS_OK;
|
||||
nsAutoChar16Buffer buffer;
|
||||
nsresult rv = SubstituteChars(mDisplayUnicode, aString, aLength, buffer, &aLength);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -4417,7 +4468,7 @@ nsFontWinSubstitute::GetBoundingMetrics(HDC aDC,
|
|||
void
|
||||
nsFontWinSubstitute::DumpFontInfo()
|
||||
{
|
||||
printf("FontName: %s @%p\n", mName, this);
|
||||
printf("FontName: %s @%p\n", mIsForIgnorable ? "For the ignorable" : mName, this);
|
||||
printf("FontType: nsFontWinSubstitute\n");
|
||||
}
|
||||
#endif // NS_DEBUG
|
||||
|
@ -5231,8 +5282,13 @@ nsFontMetricsWinA::ResolveForwards(HDC aDC,
|
|||
|
||||
//This if block is meant to speedup the process in normal situation, when
|
||||
//most characters can be found in first font
|
||||
if (currFont == mLoadedFonts[0]) {
|
||||
while (++currChar < lastChar && currFont->HasGlyph(*(currChar)) && currSubset->HasGlyph(*currChar)) ;
|
||||
NS_ASSERTION(count > 1, "only one font loaded");
|
||||
// mLoadedFont[0] == font for invisible ignorable characters
|
||||
PRUint32 firstFont = count > 1 ? 1 : 0;
|
||||
if (currFont == mLoadedFonts[firstFont]) {
|
||||
while (currChar < lastChar &&
|
||||
currFont->HasGlyph(*currChar) && currSubset->HasGlyph(*currChar) &&
|
||||
!CCMAP_HAS_CHAR_EXT(gIgnorableCCMapExt, *currChar))
|
||||
|
||||
fontSwitch.mFontWin = currSubset;
|
||||
if (!(*aFunc)(&fontSwitch, firstChar, currChar - firstChar, aData))
|
||||
|
|
|
@ -134,9 +134,12 @@ class nsFontWinSubstitute : public nsFontWin
|
|||
{
|
||||
public:
|
||||
nsFontWinSubstitute(LOGFONT* aLogFont, HFONT aFont, PRUint16* aCCMap, PRBool aDisplayUnicode);
|
||||
nsFontWinSubstitute(PRUint16* aCCMap);
|
||||
virtual ~nsFontWinSubstitute();
|
||||
|
||||
virtual PRBool HasGlyph(PRUint32 ch) {return IS_IN_BMP(ch) && IS_REPRESENTABLE(mRepresentableCharMap, ch);};
|
||||
virtual PRBool HasGlyph(PRUint32 ch) {
|
||||
return mIsForIgnorable ? CCMAP_HAS_CHAR_EXT(mCCMap, ch) :
|
||||
IS_IN_BMP(ch) && IS_REPRESENTABLE(mRepresentableCharMap, ch);};
|
||||
virtual void SetRepresentable(PRUint32 ch) { if (IS_IN_BMP(ch)) SET_REPRESENTABLE(mRepresentableCharMap, ch); };
|
||||
virtual PRInt32 GetWidth(HDC aDC, const PRUnichar* aString, PRUint32 aLength);
|
||||
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
|
||||
|
@ -153,6 +156,7 @@ public:
|
|||
#endif
|
||||
private:
|
||||
PRBool mDisplayUnicode;
|
||||
PRBool mIsForIgnorable;
|
||||
|
||||
//We need to have a easily operatable charmap for substitute font
|
||||
PRUint32 mRepresentableCharMap[UCS2_MAP_LEN];
|
||||
|
|
|
@ -37,11 +37,14 @@
|
|||
|
||||
# This script is used to generate precompiled CCMap files.
|
||||
# See bug 180266 for details.
|
||||
#
|
||||
# Revised to support extended CCMaps for non-BMP characters : 2003-09-19 (bug 205387)
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
use vars qw($fill_fmt $fu_sz);
|
||||
use vars qw($e_mid_offset $e_pg_offset $f_mid_offset $f_pg_offset);
|
||||
use vars qw($e_mid_offset $e_pg_offset);
|
||||
|
||||
(@ARGV < 1 ) and usage();
|
||||
|
||||
|
@ -57,6 +60,7 @@ if (@ARGV >= 2) {
|
|||
"\t The class spec. in the input file will be ignored.\n";
|
||||
}
|
||||
|
||||
use constant N_PLANES => 17; # BMP + 16 non-BMP planes
|
||||
use constant PLANE_SZ => 0x10000;
|
||||
use constant MID_SZ => PLANE_SZ / 16;
|
||||
use constant PG_SZ => MID_SZ / 16;
|
||||
|
@ -78,22 +82,13 @@ $fu_sz = length(pack $fill_fmt, 0); # fillinfo unit size in byte (size of short)
|
|||
|
||||
$e_mid_offset = 16;
|
||||
$e_pg_offset = 32;
|
||||
$f_pg_offset = 0;
|
||||
$f_mid_offset = 0;
|
||||
|
||||
my @ccmap = ();
|
||||
my %pg_offsets = ();
|
||||
my %pg_flags = ();
|
||||
my @fillinfo = ();
|
||||
my %comments = ();
|
||||
|
||||
#get all upper pointers to point at empty mid pointers
|
||||
push @ccmap, ($e_mid_offset) x 16;
|
||||
#get all mid-pointers to point at empty page.
|
||||
push @ccmap, ($e_pg_offset) x 16;
|
||||
push @ccmap, (0) x 16; # empty pg
|
||||
|
||||
|
||||
&read_input(\@fillinfo,$ifh,\%comments);
|
||||
my $planes = &read_input(\@fillinfo,$ifh,\%comments);
|
||||
|
||||
if (!defined($class) && !defined($comments{'CLASS'}))
|
||||
{
|
||||
|
@ -104,58 +99,57 @@ if (!defined($class) && !defined($comments{'CLASS'}))
|
|||
|
||||
$class = $comments{'CLASS'} if (! defined($class));
|
||||
|
||||
foreach my $mid (0 .. 15)
|
||||
my $have_non_bmp = 0;
|
||||
|
||||
# add the non_bmp flag and the bmp ccmap size (default to 0)
|
||||
# at the very beginning if there are non-bmp characters.
|
||||
if ($planes & 0x1fe) {
|
||||
push @ccmap, (1, 0);
|
||||
$have_non_bmp = 1;
|
||||
}
|
||||
|
||||
my $plane_idx_offset;
|
||||
foreach my $plane (0 .. ($have_non_bmp ? 16 : 0))
|
||||
{
|
||||
my(@mid_fill) = splice @fillinfo, 0, MID_FILL_SZ;
|
||||
# convert 256(MID_FILL_SZ) 16bit integers to a string of 256 * $fu_sz
|
||||
# characters.
|
||||
my($mid_str) = pack $fill_fmt x MID_FILL_SZ, @mid_fill;
|
||||
my @plane_ccmap = add_plane(\@ccmap, \@fillinfo, $plane);
|
||||
my $size = @plane_ccmap;
|
||||
push @ccmap, @plane_ccmap;
|
||||
if ($plane == 0 && $have_non_bmp) {
|
||||
$ccmap[1] = $size;
|
||||
# add 2 for non-BMP flag and BMP plane size
|
||||
# that have negative indices in C++.
|
||||
$plane_idx_offset = $size + 2;
|
||||
|
||||
# for an empty mid, upper-pointer is already pointing to the empty mid.
|
||||
next if ($mid_str eq "\0" x ($fu_sz * MID_FILL_SZ));
|
||||
# 'Flag' the offset as holding the plane indices (any negative
|
||||
# number would do)
|
||||
$pg_flags{$plane_idx_offset} = -1;
|
||||
$pg_flags{$plane_idx_offset + 16} = -1;
|
||||
|
||||
# for a full mid, add full mid if necessary.
|
||||
if ($mid_str eq "\xff" x ($fu_sz * MID_FILL_SZ)) {
|
||||
($f_mid_offset, $f_pg_offset) =
|
||||
add_full_mid(\@ccmap, $f_pg_offset) unless ($f_mid_offset);
|
||||
$ccmap[$mid] = $f_mid_offset;
|
||||
next;
|
||||
}
|
||||
# plane indices are 16 PRUint32's(not 16 PRUint16's).
|
||||
# In Perl, we assign each PRUint32 two slots in @ccmap (in BE order)
|
||||
my $e_plane_offset = $size + 16 * 2;
|
||||
|
||||
my $mid_offset = add_new_mid(\@ccmap,$mid);
|
||||
|
||||
foreach my $pg (0 .. 15) {
|
||||
my(@pg_fill) = splice @mid_fill, 0, PG_FILL_SZ;
|
||||
my($pg_str) = pack $fill_fmt x PG_FILL_SZ, @pg_fill;
|
||||
|
||||
# for an empty pg, mid-pointer is already pointing to the empty page.
|
||||
next if ($pg_str eq "\x0" x ($fu_sz * PG_FILL_SZ));
|
||||
|
||||
# for a full pg, add the full pg if necessary.
|
||||
# and set the mid-pointer to the full pg offset.
|
||||
if ($pg_str eq "\xff" x ($fu_sz * PG_FILL_SZ)) {
|
||||
if (! $f_pg_offset) {
|
||||
$f_pg_offset = @ccmap;
|
||||
#for the full pg, endianess and ALU size are immaterial.
|
||||
push @ccmap, (0xffff) x 16;
|
||||
}
|
||||
$ccmap[$mid_offset + $pg ] = $f_pg_offset;
|
||||
next;
|
||||
# set plane indices to the empty plane by default
|
||||
foreach my $i (1 .. 16) {
|
||||
# split PRUint32 into two PRUint16's in BE
|
||||
push @ccmap, $e_plane_offset >> 16;
|
||||
push @ccmap, $e_plane_offset & 0xffff;
|
||||
}
|
||||
# add 'the' empty plane;
|
||||
push @ccmap, (0) x 16;
|
||||
}
|
||||
if ($plane > 0) {
|
||||
if ($size > 0) {
|
||||
# split PRUint32 into two PRUint16's in BE.
|
||||
# subtract 2 for non-BMP flag and BMP plane size
|
||||
# that have negative indices in C++.
|
||||
$ccmap[$plane_idx_offset + ($plane - 1) * 2] = (@ccmap - $size - 2) >> 16;
|
||||
$ccmap[$plane_idx_offset + ($plane - 1) * 2 + 1] = (@ccmap - $size -2) & 0xffff;
|
||||
}
|
||||
|
||||
$ccmap[$mid_offset + $pg] = @ccmap;
|
||||
|
||||
# 'Flag' the offset as the beginning of a page with actual data as
|
||||
# opposed to pointer sections.
|
||||
$pg_offsets{scalar @ccmap} = @ccmap;
|
||||
|
||||
push @ccmap, @pg_fill;
|
||||
}
|
||||
}
|
||||
|
||||
&print_ccmap(\@ccmap, \%pg_offsets, $class . ".ccmap", \%comments);
|
||||
#&print_ccmap(\@ccmap, "32BE", \%pg_offsets, $class . ".32be", \%comments);
|
||||
#&print_ccmap(\@ccmap, "64BE", \%pg_offsets, $class . ".64be", \%comments);
|
||||
&print_ccmap(\@ccmap, \%pg_flags, $class, \%comments, $have_non_bmp);
|
||||
|
||||
exit 0;
|
||||
|
||||
|
@ -183,7 +177,10 @@ USAGE
|
|||
sub read_input
|
||||
{
|
||||
my($fillinfo_p, $input, $comments_p) = @_;
|
||||
@$fillinfo_p = (0) x FILL_SZ;
|
||||
@$fillinfo_p = (0) x (FILL_SZ * N_PLANES);
|
||||
|
||||
# init bitfield for plane flags (17bits : BMP + 16 non-BMP planes)
|
||||
my $planes = 0;
|
||||
my($lc)=0;
|
||||
while (<$input>)
|
||||
{
|
||||
|
@ -206,19 +203,25 @@ sub read_input
|
|||
next if /^0x.*[^0-9a-f]+.*/;
|
||||
|
||||
my $usv = oct $u;
|
||||
if ( 0xd800 <= $usv && $usv <= 0xdfff) { #surrogate pair
|
||||
if ( 0xd800 <= $usv && $usv <= 0xdfff || # surrogate code points
|
||||
$usv > 0x10ffff ) {
|
||||
printf STDERR "Invalid input $u at %4d\n", $lc;
|
||||
next;
|
||||
}
|
||||
$fillinfo_p->[($usv >> 4) & 0xfff] |= (1 << ($usv & 0x0f));
|
||||
$fillinfo_p->[($usv >> 4)] |= (1 << ($usv & 0x0f));
|
||||
# printf STDERR "input %s(%04x) \@line %d : put %04x @ %04x\n",
|
||||
# $u,$usv, $lc, (1 << ($usv & 0x0f)), ($usv >> 4) & 0xfff;
|
||||
|
||||
$comments_p->{$usv} = "";
|
||||
# turn on plane flags
|
||||
$planes |= (1 << ($usv >> 16));
|
||||
|
||||
my $key = sprintf("0X%06X", $usv);
|
||||
$comments_p->{$key} = "";
|
||||
|
||||
# Remove '/*' and '*/' (C style comment) or '//' (C++ style comment)
|
||||
# or ':' and store only the textual content of the comment.
|
||||
if (defined($comment)) {
|
||||
($comments_p->{$usv} = $comment)
|
||||
($comments_p->{$key} = $comment)
|
||||
=~ s !
|
||||
(?:/\*|//|:)? # '/*', '//' or ':' or NULL. Do not store.
|
||||
\s* # zero or more of white space(s)
|
||||
|
@ -229,6 +232,8 @@ sub read_input
|
|||
!$1!sx # replace the whole match with $1 stored above.
|
||||
}
|
||||
}
|
||||
|
||||
return $planes;
|
||||
}
|
||||
|
||||
sub add_full_mid
|
||||
|
@ -255,11 +260,90 @@ sub add_new_mid
|
|||
return $mid_offset;
|
||||
}
|
||||
|
||||
sub add_plane
|
||||
{
|
||||
my ($full_ccmap_p, $fillinfo_p, $plane) = @_;
|
||||
# my @ccmap = @$ccmap_p;
|
||||
my @ccmap = (); # plane ccmap
|
||||
my(@fillinfo) = splice @$fillinfo_p, 0, FILL_SZ;
|
||||
# convert 4096(FILL_SZ) 16bit integers to a string of 4096 * $fu_sz
|
||||
# characters.
|
||||
my($plane_str) = pack $fill_fmt x FILL_SZ, @fillinfo;
|
||||
|
||||
# empty plane
|
||||
if ($plane_str eq "\0" x ($fu_sz * FILL_SZ)) {
|
||||
# for non-BMP plane, the default empty plane ccmap would work.
|
||||
# for BMP, we need 'self-referring' folded CCMap (the smallest CCMap)
|
||||
push @ccmap, (0) x 16 if (!$plane);
|
||||
return @ccmap;
|
||||
}
|
||||
|
||||
#get all upper pointers to point at empty mid pointers
|
||||
push @ccmap, ($e_mid_offset) x 16;
|
||||
#get all mid-pointers to point at empty page.
|
||||
push @ccmap, ($e_pg_offset) x 16;
|
||||
push @ccmap, (0) x 16; # empty pg
|
||||
|
||||
my $f_mid_offset = 0;
|
||||
my $f_pg_offset;
|
||||
|
||||
foreach my $mid (0 .. 15)
|
||||
{
|
||||
my(@mid_fill) = splice @fillinfo, 0, MID_FILL_SZ;
|
||||
# convert 256(MID_FILL_SZ) 16bit integers to a string of 256 * $fu_sz
|
||||
# characters.
|
||||
my($mid_str) = pack $fill_fmt x MID_FILL_SZ, @mid_fill;
|
||||
|
||||
# for an empty mid, upper-pointer is already pointing to the empty mid.
|
||||
next if ($mid_str eq "\0" x ($fu_sz * MID_FILL_SZ));
|
||||
|
||||
# for a full mid, add full mid if necessary.
|
||||
if ($mid_str eq "\xff" x ($fu_sz * MID_FILL_SZ)) {
|
||||
($f_mid_offset, $f_pg_offset) =
|
||||
add_full_mid(\@ccmap, $f_pg_offset) unless ($f_mid_offset);
|
||||
$ccmap[$mid] = $f_mid_offset;
|
||||
next;
|
||||
}
|
||||
|
||||
my $mid_offset = add_new_mid(\@ccmap,$mid);
|
||||
|
||||
foreach my $pg (0 .. 15) {
|
||||
my(@pg_fill) = splice @mid_fill, 0, PG_FILL_SZ;
|
||||
my($pg_str) = pack $fill_fmt x PG_FILL_SZ, @pg_fill;
|
||||
|
||||
# for an empty pg, mid-pointer is already pointing to the empty page.
|
||||
next if ($pg_str eq "\x0" x ($fu_sz * PG_FILL_SZ));
|
||||
|
||||
# for a full pg, add the full pg if necessary.
|
||||
# and set the mid-pointer to the full pg offset.
|
||||
if ($pg_str eq "\xff" x ($fu_sz * PG_FILL_SZ)) {
|
||||
if (! $f_pg_offset) {
|
||||
$f_pg_offset = @ccmap;
|
||||
#for the full pg, endianess and ALU size are immaterial.
|
||||
push @ccmap, (0xffff) x 16;
|
||||
}
|
||||
$ccmap[$mid_offset + $pg] = $f_pg_offset;
|
||||
next;
|
||||
}
|
||||
|
||||
$ccmap[$mid_offset + $pg] = @ccmap;
|
||||
|
||||
# 'Flag' the offset as the beginning of a page with actual data as
|
||||
# opposed to pointer sections.
|
||||
$pg_flags{(scalar @$full_ccmap_p) + (scalar @ccmap)} = @ccmap;
|
||||
|
||||
push @ccmap, @pg_fill;
|
||||
}
|
||||
}
|
||||
return @ccmap;
|
||||
}
|
||||
|
||||
sub print_ccmap
|
||||
{
|
||||
my($ccmap_p,$pg_offset_p, $ofn, $comments_p) = @_;
|
||||
my($ccmap_p,$pg_flags_p, $class, $comments_p, $is_ext) = @_;
|
||||
|
||||
my(@idxlist);
|
||||
|
||||
my $ofn = $class . ($is_ext ? ".x-ccmap" : ".ccmap");
|
||||
|
||||
open OUT, "> $ofn" or
|
||||
die "cannot open $ofn for output\n";
|
||||
|
@ -276,14 +360,14 @@ sub print_ccmap
|
|||
|
||||
print OUT "\n";
|
||||
|
||||
for my $usv (sort keys %$comments_p) {
|
||||
next if ($usv =~ /CLASS/);
|
||||
printf OUT " 0X%04X : %s\n", $usv, $comments_p->{$usv};
|
||||
for my $key (sort keys %$comments_p) {
|
||||
next if ($key !~ /^0X/);
|
||||
printf OUT " %s : %s\n", $key, $comments_p->{$key};
|
||||
}
|
||||
|
||||
printf OUT "*/\n\n";
|
||||
|
||||
|
||||
my(@idxlist, @int16toint32);
|
||||
|
||||
# When CCMap is accessed, (PRUint16 *) is casted to
|
||||
# the pointer type of the ALU of a machine.
|
||||
|
@ -292,28 +376,48 @@ sub print_ccmap
|
|||
# machines with 32/64 bit ALU, two/four 16bit words
|
||||
# have to be rearranged to be interpreted correctly
|
||||
# as 32bit or 64bit integers with the 16bit word
|
||||
# at the lowest addr. taking the highest place value.
|
||||
# at the lowest address taking the highest place value.
|
||||
# This shuffling is NOT necessary for the upper pointer section
|
||||
# and mid-pointer sections.
|
||||
|
||||
foreach my $fmt ("LE", "32BE", "64BE")
|
||||
# If non-BMP characters are presente, 16 plane indices
|
||||
# (32bit integers stored in two 16bit shorts in
|
||||
# BE order) have to be treated differently based on the
|
||||
# the endianness as well.
|
||||
|
||||
# For BMP-only CCMap, 16BE CCMap is identical to LE CCMaps.
|
||||
my @fmts = $is_ext ? ("LE", "16BE", "32BE", "64BE") : ("LE", "32BE", "64BE") ;
|
||||
foreach my $fmt (@fmts)
|
||||
{
|
||||
for ($fmt) {
|
||||
/LE/ and do {
|
||||
@idxlist = (0, 1, 2, 3);
|
||||
print OUT "#if (defined(IS_LITTLE_ENDIAN) || ALU_SIZE == 16)\n" .
|
||||
"// Precompiled CCMap for Big Endian(16bit)/Little" .
|
||||
" Endian(16/32/64bit) \n";
|
||||
@int16toint32 = (1, 0, 3, 2);
|
||||
print OUT $is_ext ?
|
||||
"#if defined(IS_LITTLE_ENDIAN)\n" .
|
||||
"// Precompiled CCMap for Little Endian(16/32/64bit) \n" :
|
||||
"#if (defined(IS_LITTLE_ENDIAN) || ALU_SIZE == 16)\n" .
|
||||
"// Precompiled CCMap for Little Endian(16/32/64bit)\n" .
|
||||
"// and Big Endian(16bit)\n";
|
||||
last;
|
||||
};
|
||||
/16BE/ and do {
|
||||
@idxlist = (0, 1, 2, 3);
|
||||
@int16toint32 = (0, 1, 2, 3);
|
||||
print OUT "#elif (ALU_SIZE == 16)\n" .
|
||||
"// Precompiled CCMap for Big Endian(16bit)\n";
|
||||
last;
|
||||
};
|
||||
/32BE/ and do {
|
||||
@idxlist = (1, 0, 3, 2);
|
||||
@int16toint32 = (0, 1, 2, 3);
|
||||
print OUT "#elif (ALU_SIZE == 32)\n" .
|
||||
"// Precompiled CCMap for Big Endian(32bit)\n";
|
||||
last;
|
||||
};
|
||||
/64BE/ and do {
|
||||
@idxlist = (3, 2, 1, 0);
|
||||
@int16toint32 = (0, 1, 2, 3);
|
||||
print OUT "#elif (ALU_SIZE == 64)\n" .
|
||||
"// Precompiled CCMap for Big Endian(64bit)\n";
|
||||
last;
|
||||
|
@ -321,13 +425,19 @@ sub print_ccmap
|
|||
}
|
||||
|
||||
my($offset) = 0;
|
||||
if ($is_ext) {
|
||||
printf OUT "/* EXTFLG */ 0x%04X,0x%04X,\n", $ccmap_p->[0], $ccmap_p->[1];
|
||||
$offset = 2;
|
||||
}
|
||||
|
||||
while ($offset < @$ccmap_p) {
|
||||
printf OUT "/* %04x */ ", $offset;
|
||||
printf OUT "/* %06x */ ", $offset - ($is_ext ? 2 : 0);
|
||||
for my $i (0 .. 3) {
|
||||
for my $j (defined($pg_offset_p->{$offset}) ? @idxlist : (0,1,2,3)) {
|
||||
for my $j (defined($pg_flags_p->{$offset}) ?
|
||||
($pg_flags_p->{$offset} > 0 ? @idxlist : @int16toint32) : (0,1,2,3)) {
|
||||
printf OUT "0x%04X,", $ccmap_p->[$offset + $i * 4 + $j];
|
||||
}
|
||||
print OUT "\n " if $i==1;
|
||||
print OUT "\n " if $i==1;
|
||||
}
|
||||
print OUT "\n";
|
||||
$offset += 16;
|
||||
|
@ -348,25 +458,28 @@ sub print_preamble
|
|||
{
|
||||
|
||||
my($class) = @_;
|
||||
|
||||
sprintf <<PREAMBLE;
|
||||
sprintf <<PREAMBLE;
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
* 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 Communicator client code.
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* Contributor(s): Jungshik Shin <jshin\@mailaps.org> (Original developer)
|
||||
* The Initial Developer of the Original Code is
|
||||
* Jungshik Shin <jshin\@mailaps.org>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -374,11 +487,11 @@ sub print_preamble
|
|||
* 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 NPL, indicate your
|
||||
* 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 NPL, the GPL or the LGPL.
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
@ -402,14 +515,15 @@ sub print_preamble
|
|||
|
||||
CLASS::$class
|
||||
DESCRIPTION:: description of a character class
|
||||
FILE:: mozilla source file to include output files
|
||||
FILE:: mozilla source file to include the output file
|
||||
|
||||
|
||||
Then, run the following in the current directory.
|
||||
|
||||
perl ccmapbin.pl input_file [$class]
|
||||
|
||||
which will generate $class.ccmap.
|
||||
which will generate $class.ccmap (or $class.x-ccmap if the ccmap
|
||||
includes non-BMP characters.)
|
||||
|
||||
(see bug 180266 and bug 167136)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче