[PDF] Add font subsetting using the sfntly library.
Patch from Arthur Hsu, original CL: http://codereview.chromium.org/7513003/ Review URL: http://codereview.appspot.com/4828041 git-svn-id: http://skia.googlecode.com/svn/trunk@1957 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
9859428e71
commit
1f16589855
@ -135,6 +135,10 @@
|
||||
*/
|
||||
//#define SK_ALLOW_LARGE_PDF_SCALARS
|
||||
|
||||
/* Define this to provide font subsetter in PDF generation.
|
||||
*/
|
||||
//#define SK_SFNTLY_SUBSETTER "sfntly/subsetter/font_subsetter.h"
|
||||
|
||||
/* Define this to remove dimension checks on bitmaps. Not all blits will be
|
||||
correct yet, so this is mostly for debugging the implementation.
|
||||
*/
|
||||
|
@ -34,6 +34,10 @@
|
||||
#include "SkTypes.h"
|
||||
#include "SkUtils.h"
|
||||
|
||||
#if defined (SK_SFNTLY_SUBSETTER)
|
||||
#include SK_SFNTLY_SUBSETTER
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -427,6 +431,63 @@ static SkPDFStream* generate_tounicode_cmap(
|
||||
return new SkPDFStream(cmapStream.get());
|
||||
}
|
||||
|
||||
static void sk_delete_array(const void* ptr, size_t, void*) {
|
||||
// Use C-style cast to cast away const and cast type simultaneously.
|
||||
delete[] (unsigned char*)ptr;
|
||||
}
|
||||
|
||||
static int get_subset_font_stream(const char* fontName,
|
||||
const SkTypeface* typeface,
|
||||
const SkPDFGlyphSet* subset,
|
||||
SkPDFStream** fontStream) {
|
||||
SkRefPtr<SkStream> fontData =
|
||||
SkFontHost::OpenStream(SkTypeface::UniqueID(typeface));
|
||||
fontData->unref(); // SkRefPtr and OpenStream both took a ref.
|
||||
|
||||
int fontSize = fontData->getLength();
|
||||
|
||||
#if defined (SK_SFNTLY_SUBSETTER)
|
||||
// Generate glyph id array.
|
||||
SkTDArray<unsigned int> glyphIDs;
|
||||
glyphIDs.push(0); // Always include glyph 0.
|
||||
for (int i = 0; i <= SK_MaxU16; ++i) {
|
||||
if (subset->has(i)) {
|
||||
glyphIDs.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Read font into buffer.
|
||||
SkPDFStream* subsetFontStream = NULL;
|
||||
SkTDArray<unsigned char> originalFont;
|
||||
originalFont.setCount(fontSize);
|
||||
if (fontData->read(originalFont.begin(), fontSize) == (size_t)fontSize) {
|
||||
unsigned char* subsetFont = NULL;
|
||||
int subsetFontSize = SfntlyWrapper::SubsetFont(fontName,
|
||||
originalFont.begin(),
|
||||
fontSize,
|
||||
glyphIDs.begin(),
|
||||
glyphIDs.count(),
|
||||
&subsetFont);
|
||||
if (subsetFontSize > 0 && subsetFont != NULL) {
|
||||
SkData* data = SkData::NewWithProc(subsetFont,
|
||||
subsetFontSize,
|
||||
sk_delete_array,
|
||||
NULL);
|
||||
subsetFontStream = new SkPDFStream(data);
|
||||
fontSize = subsetFontSize;
|
||||
}
|
||||
}
|
||||
if (subsetFontStream) {
|
||||
*fontStream = subsetFontStream;
|
||||
return fontSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fail over: just embed the whole font.
|
||||
*fontStream = new SkPDFStream(fontData.get());
|
||||
return fontSize;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class SkPDFGlyphSet
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -858,15 +919,19 @@ bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth,
|
||||
|
||||
switch (getType()) {
|
||||
case SkAdvancedTypefaceMetrics::kTrueType_Font: {
|
||||
// TODO(arthurhsu): sfntly font subsetting
|
||||
SkRefPtr<SkStream> fontData =
|
||||
SkFontHost::OpenStream(SkTypeface::UniqueID(typeface()));
|
||||
fontData->unref(); // SkRefPtr and OpenStream both took a ref.
|
||||
SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get());
|
||||
// Font subsetting
|
||||
SkPDFStream* rawStream = NULL;
|
||||
int fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(),
|
||||
typeface(),
|
||||
subset,
|
||||
&rawStream);
|
||||
SkASSERT(fontSize);
|
||||
SkASSERT(rawStream);
|
||||
SkRefPtr<SkPDFStream> fontStream = rawStream;
|
||||
// SkRefPtr and new both ref()'d fontStream, pass one.
|
||||
addResource(fontStream.get());
|
||||
|
||||
fontStream->insertInt("Length1", fontData->getLength());
|
||||
fontStream->insertInt("Length1", fontSize);
|
||||
descriptor->insert("FontFile2",
|
||||
new SkPDFObjRef(fontStream.get()))->unref();
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user