[PDF] Improve efficiency of glyph id collection during font subsetting.

Patch from Arthur Hsu, original CL: http://codereview.appspot.com/4828044/

Review URL: http://codereview.appspot.com/4798057

git-svn-id: http://skia.googlecode.com/svn/trunk@1978 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
vandebo@chromium.org 2011-07-27 20:59:55 +00:00
parent 93225ff5d5
commit 17e66e2d34
5 changed files with 38 additions and 6 deletions

View File

@ -18,6 +18,7 @@
#define SkBitSet_DEFINED
#include "SkTypes.h"
#include "SkTDArray.h"
class SkBitSet {
public:
@ -47,6 +48,10 @@ public:
*/
bool orBits(const SkBitSet& source);
/** Export set bits to unsigned int array. (used in font subsetting)
*/
void exportTo(SkTDArray<uint32_t>* array) const;
private:
SkAutoFree fBitData;
// Dword (32-bit) count of the bitset.

View File

@ -35,6 +35,7 @@ public:
void set(const uint16_t* glyphIDs, int numGlyphs);
bool has(uint16_t glyphID) const;
void merge(const SkPDFGlyphSet& usage);
void exportTo(SkTDArray<uint32_t>* glyphIDs) const;
private:
SkBitSet fBitSet;

View File

@ -89,3 +89,19 @@ bool SkBitSet::orBits(const SkBitSet& source) {
}
return true;
}
void SkBitSet::exportTo(SkTDArray<uint32_t>* array) const {
SkASSERT(array);
uint32_t* data = (uint32_t*)fBitData.get();
for (unsigned int i = 0; i < fDwordCount; ++i) {
uint32_t value = data[i];
if (value) { // There are set bits
unsigned int index = i * 32;
for (unsigned int j = 0; j < 32; ++j) {
if (0x1 & (value >> j)) {
array->push(index + j);
}
}
}
}
}

View File

@ -448,13 +448,9 @@ static int get_subset_font_stream(const char* fontName,
#if defined (SK_SFNTLY_SUBSETTER)
// Generate glyph id array.
SkTDArray<unsigned int> glyphIDs;
SkTDArray<uint32_t> glyphIDs;
glyphIDs.push(0); // Always include glyph 0.
for (int i = 0; i <= SK_MaxU16; ++i) {
if (subset->has(i)) {
glyphIDs.push(i);
}
}
subset->exportTo(&glyphIDs);
// Read font into buffer.
SkPDFStream* subsetFontStream = NULL;
@ -462,6 +458,10 @@ static int get_subset_font_stream(const char* fontName,
originalFont.setCount(fontSize);
if (fontData->read(originalFont.begin(), fontSize) == (size_t)fontSize) {
unsigned char* subsetFont = NULL;
// sfntly requires unsigned int* to be passed in, as far as we know,
// unsigned int is equivalent to uint32_t on all platforms.
SK_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t),
unsigned_int_not_32_bits);
int subsetFontSize = SfntlyWrapper::SubsetFont(fontName,
originalFont.begin(),
fontSize,
@ -509,6 +509,10 @@ void SkPDFGlyphSet::merge(const SkPDFGlyphSet& usage) {
fBitSet.orBits(usage.fBitSet);
}
void SkPDFGlyphSet::exportTo(SkTDArray<unsigned int>* glyphIDs) const {
fBitSet.exportTo(glyphIDs);
}
///////////////////////////////////////////////////////////////////////////////
// class SkPDFGlyphSetMap
///////////////////////////////////////////////////////////////////////////////

View File

@ -21,6 +21,12 @@ static void TestBitSet(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, set0.isBitSet(24) == true);
REPORTER_ASSERT(reporter, set0.isBitSet(35) == true);
SkTDArray<unsigned int> data;
set0.exportTo(&data);
REPORTER_ASSERT(reporter, data.count() == 2);
REPORTER_ASSERT(reporter, data[0] == 24);
REPORTER_ASSERT(reporter, data[1] == 35);
set1.setBit(12345, true);
set1.orBits(set0);
REPORTER_ASSERT(reporter, set0.isBitSet(12345) == false);