зеркало из https://github.com/mozilla/gecko-dev.git
speed up setting of code points. bug 386375. r=vlad
This commit is contained in:
Родитель
bbec522fd5
Коммит
8e8284090f
|
@ -242,11 +242,18 @@ static PRUint8 CharRangeBit(PRUint32 ch) {
|
|||
|
||||
|
||||
class gfxSparseBitSet {
|
||||
public:
|
||||
private:
|
||||
enum { BLOCK_SIZE = 32 };
|
||||
enum { BLOCK_SIZE_BITS = BLOCK_SIZE * 8 };
|
||||
|
||||
struct Block {
|
||||
Block(unsigned char memsetValue = 0) { memset(mBits, memsetValue, BLOCK_SIZE); }
|
||||
PRUint8 mBits[BLOCK_SIZE];
|
||||
};
|
||||
|
||||
public:
|
||||
PRBool test(PRUint32 aIndex) {
|
||||
PRUint32 blockIndex = aIndex/(BLOCK_SIZE*8);
|
||||
PRUint32 blockIndex = aIndex/BLOCK_SIZE_BITS;
|
||||
if (blockIndex >= mBlocks.Length())
|
||||
return PR_FALSE;
|
||||
Block *block = mBlocks[blockIndex];
|
||||
|
@ -254,26 +261,65 @@ public:
|
|||
return PR_FALSE;
|
||||
return ((block->mBits[(aIndex/8) & (BLOCK_SIZE - 1)]) & (1 << (aIndex & 0x7))) != 0;
|
||||
}
|
||||
|
||||
|
||||
void set(PRUint32 aIndex) {
|
||||
PRUint32 blockIndex = aIndex/(BLOCK_SIZE*8);
|
||||
PRUint32 blockIndex = aIndex/BLOCK_SIZE_BITS;
|
||||
if (blockIndex >= mBlocks.Length()) {
|
||||
nsAutoPtr<Block> *blocks = mBlocks.AppendElements(blockIndex + 1 - mBlocks.Length());
|
||||
if (!blocks) // OOM
|
||||
if (NS_UNLIKELY(!blocks)) // OOM
|
||||
return;
|
||||
}
|
||||
Block *block = mBlocks[blockIndex];
|
||||
if (!block) {
|
||||
block = new Block;
|
||||
if (!block) // OOM
|
||||
if (NS_UNLIKELY(!block)) // OOM
|
||||
return;
|
||||
memset(block, 0, sizeof(Block));
|
||||
mBlocks[blockIndex] = block;
|
||||
}
|
||||
block->mBits[(aIndex/8) & (BLOCK_SIZE - 1)] |= 1 << (aIndex & 0x7);
|
||||
}
|
||||
|
||||
PRUint32 getsize() {
|
||||
void SetRange(PRUint32 aStart, PRUint32 aEnd) {
|
||||
const PRUint32 startIndex = aStart/BLOCK_SIZE_BITS;
|
||||
const PRUint32 endIndex = aEnd/BLOCK_SIZE_BITS;
|
||||
|
||||
if (endIndex >= mBlocks.Length()) {
|
||||
PRUint32 numNewBlocks = endIndex + 1 - mBlocks.Length();
|
||||
nsAutoPtr<Block> *blocks = mBlocks.AppendElements(numNewBlocks);
|
||||
if (NS_UNLIKELY(!blocks)) // OOM
|
||||
return;
|
||||
}
|
||||
|
||||
for (PRUint32 i = startIndex; i <= endIndex; ++i) {
|
||||
const PRUint32 blockFirstBit = i * BLOCK_SIZE_BITS;
|
||||
const PRUint32 blockLastBit = blockFirstBit + BLOCK_SIZE_BITS - 1;
|
||||
|
||||
Block *block = mBlocks[i];
|
||||
if (!block) {
|
||||
PRBool fullBlock = PR_FALSE;
|
||||
if (aStart <= blockFirstBit && aEnd >= blockLastBit)
|
||||
fullBlock = PR_TRUE;
|
||||
|
||||
block = new Block(fullBlock ? 0xFF : 0);
|
||||
|
||||
if (NS_UNLIKELY(!block)) // OOM
|
||||
return;
|
||||
mBlocks[i] = block;
|
||||
|
||||
if (fullBlock)
|
||||
continue;
|
||||
}
|
||||
|
||||
const PRUint32 start = aStart > blockFirstBit ? aStart - blockFirstBit : 0;
|
||||
const PRUint32 end = PR_MIN(aEnd - blockFirstBit, BLOCK_SIZE_BITS - 1);
|
||||
|
||||
for (PRUint32 bit = start; bit <= end; ++bit) {
|
||||
block->mBits[bit/8] |= 1 << (bit & 0x7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 GetSize() {
|
||||
PRUint32 size = 0;
|
||||
for (PRUint32 i = 0; i < mBlocks.Length(); i++)
|
||||
if (mBlocks[i])
|
||||
|
@ -281,14 +327,7 @@ public:
|
|||
return size;
|
||||
}
|
||||
|
||||
// If you want to set a lot of bits very fast, we could have Set variants
|
||||
// that set a lot of bits at once, e.g. Set(PRUint32 aStart, PRUint32 aLength)
|
||||
|
||||
private:
|
||||
struct Block {
|
||||
PRUint8 mBits[BLOCK_SIZE];
|
||||
};
|
||||
|
||||
nsTArray< nsAutoPtr<Block> > mBlocks;
|
||||
};
|
||||
|
||||
|
|
|
@ -202,16 +202,14 @@ ReadCMAPTableFormat12(PRUint8 *aBuf, PRInt32 aLength, FontEntry *aFontEntry)
|
|||
for (PRUint32 i = 0; i < numGroups; i++, groups += SizeOfGroup) {
|
||||
const PRUint32 startCharCode = ReadLongAt(groups, GroupOffsetStartCode);
|
||||
const PRUint32 endCharCode = ReadLongAt(groups, GroupOffsetEndCode);
|
||||
for (PRUint32 c = startCharCode; c <= endCharCode; ++c) {
|
||||
// XXX we should use a range setting functions on gfxSparseBitset
|
||||
// which could be a lot faster
|
||||
aFontEntry->mCharacterMap.set(c);
|
||||
aFontEntry->mCharacterMap.SetRange(startCharCode, endCharCode);
|
||||
#ifdef UPDATE_RANGES
|
||||
for (PRUint32 c = startCharCode; c <= endCharCode; ++c) {
|
||||
PRUint16 b = CharRangeBit(c);
|
||||
if (b != NO_RANGE_FOUND)
|
||||
aFontEntry->mUnicodeRanges.set(b, true);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -247,14 +245,14 @@ ReadCMAPTableFormat4(PRUint8 *aBuf, PRInt32 aLength, FontEntry *aFontEntry)
|
|||
const PRUint16 startCount = ReadShortAt16(startCounts, i);
|
||||
const PRUint16 idRangeOffset = ReadShortAt16(idRangeOffsets, i);
|
||||
if (idRangeOffset == 0) {
|
||||
for (PRUint32 c = startCount; c <= endCount; c++) {
|
||||
aFontEntry->mCharacterMap.set(c);
|
||||
aFontEntry->mCharacterMap.SetRange(startCount, endCount);
|
||||
#ifdef UPDATE_RANGES
|
||||
for (PRUint32 c = startCount; c <= endCount; c++) {
|
||||
PRUint16 b = CharRangeBit(c);
|
||||
if (b != NO_RANGE_FOUND)
|
||||
aFontEntry->mUnicodeRanges.set(b, true);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
const PRUint16 idDelta = ReadShortAt16(idDeltas, i);
|
||||
for (PRUint32 c = startCount; c <= endCount; ++c) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче