2013-08-21 16:31:37 +00:00
/*
* Copyright 2013 Google Inc .
*
* Use of this source code is governed by a BSD - style license that can be
* found in the LICENSE file .
*/
2013-06-21 21:43:09 +00:00
# include "SkPdfFont.h"
2013-06-27 13:22:42 +00:00
# include "SkStream.h"
# include "SkTypeface.h"
2013-07-10 17:09:50 +00:00
# include "SkPdfNativeTokenizer.h"
2013-06-27 13:22:42 +00:00
2013-08-16 15:05:08 +00:00
SkTDict < SkPdfStandardFontEntry > & getStandardFonts ( ) {
static SkTDict < SkPdfStandardFontEntry > gPdfStandardFonts ( 100 ) ;
2013-06-21 21:43:09 +00:00
// TODO (edisonn): , vs - ? what does it mean?
// TODO (edisonn): MT, PS, Oblique=italic?, ... what does it mean?
2013-08-16 15:05:08 +00:00
if ( gPdfStandardFonts . count ( ) = = 0 ) {
gPdfStandardFonts . set ( " Arial " , SkPdfStandardFontEntry ( " Arial " , false , false ) ) ;
gPdfStandardFonts . set ( " Arial,Bold " , SkPdfStandardFontEntry ( " Arial " , true , false ) ) ;
gPdfStandardFonts . set ( " Arial,BoldItalic " , SkPdfStandardFontEntry ( " Arial " , true , true ) ) ;
gPdfStandardFonts . set ( " Arial,Italic " , SkPdfStandardFontEntry ( " Arial " , false , true ) ) ;
gPdfStandardFonts . set ( " Arial-Bold " , SkPdfStandardFontEntry ( " Arial " , true , false ) ) ;
gPdfStandardFonts . set ( " Arial-BoldItalic " , SkPdfStandardFontEntry ( " Arial " , true , true ) ) ;
gPdfStandardFonts . set ( " Arial-BoldItalicMT " , SkPdfStandardFontEntry ( " Arial " , true , true ) ) ;
gPdfStandardFonts . set ( " Arial-BoldMT " , SkPdfStandardFontEntry ( " Arial " , true , false ) ) ;
gPdfStandardFonts . set ( " Arial-Italic " , SkPdfStandardFontEntry ( " Arial " , false , true ) ) ;
gPdfStandardFonts . set ( " Arial-ItalicMT " , SkPdfStandardFontEntry ( " Arial " , false , true ) ) ;
gPdfStandardFonts . set ( " ArialMT " , SkPdfStandardFontEntry ( " Arial " , false , false ) ) ;
gPdfStandardFonts . set ( " Courier " , SkPdfStandardFontEntry ( " Courier New " , false , false ) ) ;
gPdfStandardFonts . set ( " Courier,Bold " , SkPdfStandardFontEntry ( " Courier New " , true , false ) ) ;
gPdfStandardFonts . set ( " Courier,BoldItalic " , SkPdfStandardFontEntry ( " Courier New " , true , true ) ) ;
gPdfStandardFonts . set ( " Courier,Italic " , SkPdfStandardFontEntry ( " Courier New " , false , true ) ) ;
gPdfStandardFonts . set ( " Courier-Bold " , SkPdfStandardFontEntry ( " Courier New " , true , false ) ) ;
gPdfStandardFonts . set ( " Courier-BoldOblique " , SkPdfStandardFontEntry ( " Courier New " , true , true ) ) ;
gPdfStandardFonts . set ( " Courier-Oblique " , SkPdfStandardFontEntry ( " Courier New " , false , true ) ) ;
gPdfStandardFonts . set ( " CourierNew " , SkPdfStandardFontEntry ( " Courier New " , false , false ) ) ;
gPdfStandardFonts . set ( " CourierNew,Bold " , SkPdfStandardFontEntry ( " Courier New " , true , false ) ) ;
gPdfStandardFonts . set ( " CourierNew,BoldItalic " , SkPdfStandardFontEntry ( " Courier New " , true , true ) ) ;
gPdfStandardFonts . set ( " CourierNew,Italic " , SkPdfStandardFontEntry ( " Courier New " , false , true ) ) ;
gPdfStandardFonts . set ( " CourierNew-Bold " , SkPdfStandardFontEntry ( " Courier New " , true , false ) ) ;
gPdfStandardFonts . set ( " CourierNew-BoldItalic " , SkPdfStandardFontEntry ( " Courier New " , true , true ) ) ;
gPdfStandardFonts . set ( " CourierNew-Italic " , SkPdfStandardFontEntry ( " Courier New " , false , true ) ) ;
gPdfStandardFonts . set ( " CourierNewPS-BoldItalicMT " , SkPdfStandardFontEntry ( " Courier New " , true , true ) ) ;
gPdfStandardFonts . set ( " CourierNewPS-BoldMT " , SkPdfStandardFontEntry ( " Courier New " , true , false ) ) ;
gPdfStandardFonts . set ( " CourierNewPS-ItalicMT " , SkPdfStandardFontEntry ( " Courier New " , false , true ) ) ;
gPdfStandardFonts . set ( " CourierNewPSMT " , SkPdfStandardFontEntry ( " Courier New " , false , false ) ) ;
gPdfStandardFonts . set ( " Helvetica " , SkPdfStandardFontEntry ( " Helvetica " , false , false ) ) ;
gPdfStandardFonts . set ( " Helvetica,Bold " , SkPdfStandardFontEntry ( " Helvetica " , true , false ) ) ;
gPdfStandardFonts . set ( " Helvetica,BoldItalic " , SkPdfStandardFontEntry ( " Helvetica " , true , true ) ) ;
gPdfStandardFonts . set ( " Helvetica,Italic " , SkPdfStandardFontEntry ( " Helvetica " , false , true ) ) ;
gPdfStandardFonts . set ( " Helvetica-Bold " , SkPdfStandardFontEntry ( " Helvetica " , true , false ) ) ;
gPdfStandardFonts . set ( " Helvetica-BoldItalic " , SkPdfStandardFontEntry ( " Helvetica " , true , true ) ) ;
gPdfStandardFonts . set ( " Helvetica-BoldOblique " , SkPdfStandardFontEntry ( " Helvetica " , true , true ) ) ;
gPdfStandardFonts . set ( " Helvetica-Italic " , SkPdfStandardFontEntry ( " Helvetica " , false , true ) ) ;
gPdfStandardFonts . set ( " Helvetica-Oblique " , SkPdfStandardFontEntry ( " Helvetica " , false , true ) ) ;
gPdfStandardFonts . set ( " Times-Bold " , SkPdfStandardFontEntry ( " Times New Roman " , true , false ) ) ;
gPdfStandardFonts . set ( " Times-BoldItalic " , SkPdfStandardFontEntry ( " Times New Roman " , true , true ) ) ;
gPdfStandardFonts . set ( " Times-Italic " , SkPdfStandardFontEntry ( " Times New Roman " , false , true ) ) ;
gPdfStandardFonts . set ( " Times-Roman " , SkPdfStandardFontEntry ( " Times New Roman " , false , false ) ) ;
gPdfStandardFonts . set ( " TimesNewRoman " , SkPdfStandardFontEntry ( " Times New Roman " , false , false ) ) ;
gPdfStandardFonts . set ( " TimesNewRoman,Bold " , SkPdfStandardFontEntry ( " Times New Roman " , true , false ) ) ;
gPdfStandardFonts . set ( " TimesNewRoman,BoldItalic " , SkPdfStandardFontEntry ( " Times New Roman " , true , true ) ) ;
gPdfStandardFonts . set ( " TimesNewRoman,Italic " , SkPdfStandardFontEntry ( " Times New Roman " , false , true ) ) ;
gPdfStandardFonts . set ( " TimesNewRoman-Bold " , SkPdfStandardFontEntry ( " Times New Roman " , true , false ) ) ;
gPdfStandardFonts . set ( " TimesNewRoman-BoldItalic " , SkPdfStandardFontEntry ( " Times New Roman " , true , true ) ) ;
gPdfStandardFonts . set ( " TimesNewRoman-Italic " , SkPdfStandardFontEntry ( " Times New Roman " , false , true ) ) ;
gPdfStandardFonts . set ( " TimesNewRomanPS " , SkPdfStandardFontEntry ( " Times New Roman " , false , false ) ) ;
gPdfStandardFonts . set ( " TimesNewRomanPS-Bold " , SkPdfStandardFontEntry ( " Times New Roman " , true , false ) ) ;
gPdfStandardFonts . set ( " TimesNewRomanPS-BoldItalic " , SkPdfStandardFontEntry ( " Times New Roman " , true , true ) ) ;
gPdfStandardFonts . set ( " TimesNewRomanPS-BoldItalicMT " , SkPdfStandardFontEntry ( " Times New Roman " , true , true ) ) ;
gPdfStandardFonts . set ( " TimesNewRomanPS-BoldMT " , SkPdfStandardFontEntry ( " Times New Roman " , true , false ) ) ;
gPdfStandardFonts . set ( " TimesNewRomanPS-Italic " , SkPdfStandardFontEntry ( " Times New Roman " , false , true ) ) ;
gPdfStandardFonts . set ( " TimesNewRomanPS-ItalicMT " , SkPdfStandardFontEntry ( " Times New Roman " , false , true ) ) ;
gPdfStandardFonts . set ( " TimesNewRomanPSMT " , SkPdfStandardFontEntry ( " Times New Roman " , false , false ) ) ;
gPdfStandardFonts . set ( " Symbol " , SkPdfStandardFontEntry ( " Symbol " , false , false ) ) ;
gPdfStandardFonts . set ( " ZapfDingbats " , SkPdfStandardFontEntry ( " ZapfDingbats " , false , false ) ) ;
2013-06-21 21:43:09 +00:00
// TODO(edisonn): these are hacks. Load Post Script font name.
// see FT_Get_Postscript_Name
// Font config is not using it, yet.
//https://bugs.freedesktop.org/show_bug.cgi?id=18095
2013-06-25 20:45:40 +00:00
2013-08-16 15:05:08 +00:00
gPdfStandardFonts . set ( " Arial-Black " , SkPdfStandardFontEntry ( " Arial " , true , false ) ) ;
gPdfStandardFonts . set ( " DejaVuSans " , SkPdfStandardFontEntry ( " DejaVu Sans " , false , false ) ) ;
gPdfStandardFonts . set ( " DejaVuSansMono " , SkPdfStandardFontEntry ( " DejaVuSans Mono " , false , false ) ) ;
gPdfStandardFonts . set ( " DejaVuSansMono-Bold " , SkPdfStandardFontEntry ( " DejaVuSans Mono " , true , false ) ) ;
gPdfStandardFonts . set ( " DejaVuSansMono-Oblique " , SkPdfStandardFontEntry ( " DejaVuSans Mono " , false , true ) ) ;
gPdfStandardFonts . set ( " Georgia-Bold " , SkPdfStandardFontEntry ( " Georgia " , true , false ) ) ;
gPdfStandardFonts . set ( " Georgia-BoldItalic " , SkPdfStandardFontEntry ( " Georgia " , true , true ) ) ;
gPdfStandardFonts . set ( " Georgia-Italic " , SkPdfStandardFontEntry ( " Georgia " , false , true ) ) ;
gPdfStandardFonts . set ( " TrebuchetMS " , SkPdfStandardFontEntry ( " Trebuchet MS " , false , false ) ) ;
gPdfStandardFonts . set ( " TrebuchetMS-Bold " , SkPdfStandardFontEntry ( " Trebuchet MS " , true , false ) ) ;
gPdfStandardFonts . set ( " Verdana-Bold " , SkPdfStandardFontEntry ( " Verdana " , true , false ) ) ;
gPdfStandardFonts . set ( " WenQuanYiMicroHei " , SkPdfStandardFontEntry ( " WenQuanYi Micro Hei " , false , false ) ) ;
2013-06-25 20:45:40 +00:00
// TODO(edisonn): list all phonts available, builf post script name as in pdf spec
/*
* The PostScript name for the value of BaseFontis determined in one of two ways :
• Use the PostScript name that is an optional entry in the “ name ” table of the
TrueType font itself .
• In the absence of such an entry in the “ name ” table , derive a PostScript name
from the name by which the font is known in the host operating system : on a
Windows system , it is based on the lfFaceName fi eld in a LOGFONT structure ; in
the Mac OS , it is based on the name of the FONDresource . If the name contains
any spaces , the spaces are removed .
If the font in a source document uses a bold or italic style , but there is no font
data for that style , the host operating system will synthesize the style . In this case ,
a comma and the style name ( one of Bold , Italic , or BoldItalic ) are appended to the
font name . For example , for a TrueType font that is a bold variant of the New
*/
/*
* If the value of Subtype is MMType1 .
• If the PostScript name of the instance contains spaces , the spaces are replaced
by underscores in the value of BaseFont . For instance , as illustrated in Example
5.7 , the name “ MinionMM 366 465 11 ” ( which ends with a space character )
becomes / MinionMM_366_465_11_ .
*/
// might not work on all oses ?
//
2013-06-21 21:43:09 +00:00
}
return gPdfStandardFonts ;
}
SkTypeface * SkTypefaceFromPdfStandardFont ( const char * fontName , bool bold , bool italic ) {
2013-08-16 15:05:08 +00:00
SkTDict < SkPdfStandardFontEntry > & standardFontMap = getStandardFonts ( ) ;
2013-06-21 21:43:09 +00:00
SkTypeface * typeface = NULL ;
2013-08-16 15:05:08 +00:00
SkPdfStandardFontEntry fontData ;
2013-06-21 21:43:09 +00:00
2013-08-16 15:05:08 +00:00
if ( standardFontMap . find ( fontName , & fontData ) ) {
2013-06-21 21:43:09 +00:00
// TODO(edisonn): How does the bold/italic specified in standard definition combines with
// the one in /font key? use OR for now.
bold = bold | | fontData . fIsBold ;
italic = italic | | fontData . fIsItalic ;
typeface = SkTypeface : : CreateFromName (
fontData . fName ,
SkTypeface : : Style ( ( bold ? SkTypeface : : kBold : 0 ) |
( italic ? SkTypeface : : kItalic : 0 ) ) ) ;
} else {
typeface = SkTypeface : : CreateFromName (
fontName ,
SkTypeface : : kNormal ) ;
}
if ( typeface ) {
typeface - > ref ( ) ;
}
return typeface ;
}
2013-08-14 18:26:20 +00:00
SkPdfFont * SkPdfFont : : fontFromFontDescriptor ( SkPdfNativeDoc * doc , SkPdfFontDescriptorDictionary * fd , bool loadFromName ) {
2013-07-10 17:09:50 +00:00
// TODO(edisonn): partial implementation ... also const handling ...
2013-06-27 13:22:42 +00:00
// Only one, at most be available
2013-06-27 20:03:43 +00:00
SkPdfStream * pdfStream = NULL ;
2013-06-27 13:22:42 +00:00
if ( fd - > has_FontFile ( ) ) {
2013-07-10 17:09:50 +00:00
pdfStream = fd - > FontFile ( doc ) ;
2013-06-27 13:22:42 +00:00
} else if ( fd - > has_FontFile2 ( ) ) {
2013-07-10 17:09:50 +00:00
pdfStream = fd - > FontFile2 ( doc ) ;
2013-06-27 20:03:43 +00:00
} if ( fd - > has_FontFile3 ( ) ) {
2013-07-10 17:09:50 +00:00
pdfStream = fd - > FontFile3 ( doc ) ;
2013-06-27 20:03:43 +00:00
} else {
if ( loadFromName ) {
2013-07-10 17:09:50 +00:00
return fontFromName ( doc , fd , fd - > FontName ( doc ) . c_str ( ) ) ;
2013-06-27 13:22:42 +00:00
}
2013-06-27 20:03:43 +00:00
}
2013-06-27 13:22:42 +00:00
2013-07-23 17:43:18 +00:00
const unsigned char * uncompressedStream = NULL ;
2013-07-10 17:09:50 +00:00
size_t uncompressedStreamLength = 0 ;
2013-06-27 13:22:42 +00:00
2013-07-02 22:42:53 +00:00
// TODO(edisonn): report warning to be used in testing.
if ( ! pdfStream | |
2013-07-23 17:43:18 +00:00
! pdfStream - > GetFilteredStreamRef ( & uncompressedStream , & uncompressedStreamLength ) | |
2013-07-02 22:42:53 +00:00
! uncompressedStream | |
! uncompressedStreamLength ) {
2013-06-27 20:03:43 +00:00
return NULL ;
}
2013-07-02 22:42:53 +00:00
2013-06-27 20:03:43 +00:00
SkMemoryStream * skStream = new SkMemoryStream ( uncompressedStream , uncompressedStreamLength ) ;
SkTypeface * face = SkTypeface : : CreateFromStream ( skStream ) ;
2013-06-27 13:22:42 +00:00
2013-06-27 20:03:43 +00:00
if ( face = = NULL ) {
// TODO(edisonn): report warning to be used in testing.
return NULL ;
2013-06-27 13:22:42 +00:00
}
2013-06-27 20:03:43 +00:00
face - > ref ( ) ;
return new SkPdfStandardFont ( face ) ;
2013-06-27 13:22:42 +00:00
}
2013-08-14 18:26:20 +00:00
SkPdfFont * fontFromName ( SkPdfNativeDoc * doc , SkPdfNativeObject * obj , const char * fontName ) {
2013-06-21 21:43:09 +00:00
SkTypeface * typeface = SkTypefaceFromPdfStandardFont ( fontName , false , false ) ;
if ( typeface ! = NULL ) {
return new SkPdfStandardFont ( typeface ) ;
}
2013-06-27 13:22:42 +00:00
// TODO(edisonn): perf - make a map
2013-07-10 17:09:50 +00:00
for ( unsigned int i = 0 ; i < doc - > objects ( ) ; i + + ) {
2013-08-14 18:26:20 +00:00
SkPdfNativeObject * obj = doc - > object ( i ) ;
2013-07-23 20:47:05 +00:00
if ( ! obj | | ! obj - > isDictionary ( ) ) {
2013-07-10 17:09:50 +00:00
continue ;
}
SkPdfFontDescriptorDictionary * fd = obj - > asDictionary ( ) - > asFontDescriptorDictionary ( ) ;
if ( ! fd - > valid ( ) ) {
continue ;
}
2013-08-16 15:05:08 +00:00
if ( fd - > has_FontName ( ) & & fd - > FontName ( doc ) . equals ( fontName ) ) {
2013-07-10 17:09:50 +00:00
SkPdfFont * font = SkPdfFont : : fontFromFontDescriptor ( doc , fd , false ) ;
if ( font ) {
return font ;
} else {
// failed to load font descriptor
break ;
2013-06-27 13:22:42 +00:00
}
}
}
// TODO(edisonn): warning/report issue
2013-06-21 21:43:09 +00:00
return SkPdfFont : : Default ( ) ;
}
2013-08-14 18:26:20 +00:00
SkPdfFont * SkPdfFont : : fontFromPdfDictionaryOnce ( SkPdfNativeDoc * doc , SkPdfFontDictionary * dict ) {
// TODO(edisonn): keep the type in a smart way in the SkPdfNativeObject
2013-07-10 17:09:50 +00:00
// 1) flag, isResolved (1bit): reset at reset, add/remove/update (array) and set(dict)
// in a tree like structure, 3-4 bits for all the datatypes inheriting from obj (int, real, ...)
// if is a dict, reserveve a few bytes to encode type of dict, and so on like in a tree
// issue: type can be determined from context! atribute night be missing/wrong
switch ( doc - > mapper ( ) - > mapFontDictionary ( dict ) ) {
2013-08-14 18:26:20 +00:00
case kType0FontDictionary_SkPdfNativeObjectType :
2013-07-10 17:09:50 +00:00
return fontFromType0FontDictionary ( doc , dict - > asType0FontDictionary ( ) ) ;
2013-06-21 21:43:09 +00:00
2013-08-14 18:26:20 +00:00
case kTrueTypeFontDictionary_SkPdfNativeObjectType :
2013-07-10 17:09:50 +00:00
return fontFromTrueTypeFontDictionary ( doc , dict - > asTrueTypeFontDictionary ( ) ) ;
2013-06-21 21:43:09 +00:00
2013-08-14 18:26:20 +00:00
case kType1FontDictionary_SkPdfNativeObjectType :
2013-07-10 17:09:50 +00:00
return fontFromType1FontDictionary ( doc , dict - > asType1FontDictionary ( ) ) ;
2013-06-21 21:43:09 +00:00
2013-08-14 18:26:20 +00:00
case kMultiMasterFontDictionary_SkPdfNativeObjectType :
2013-07-10 17:09:50 +00:00
return fontFromMultiMasterFontDictionary ( doc , dict - > asMultiMasterFontDictionary ( ) ) ;
2013-06-21 21:43:09 +00:00
2013-08-14 18:26:20 +00:00
case kType3FontDictionary_SkPdfNativeObjectType :
2013-07-10 17:09:50 +00:00
return fontFromType3FontDictionary ( doc , dict - > asType3FontDictionary ( ) ) ;
default :
// TODO(edisonn): report error?
return NULL ;
2013-06-21 21:43:09 +00:00
}
}
2013-08-14 18:26:20 +00:00
SkPdfFont * SkPdfFont : : fontFromPdfDictionary ( SkPdfNativeDoc * doc , SkPdfFontDictionary * dict ) {
2013-07-10 17:09:50 +00:00
if ( dict = = NULL ) {
return NULL ; // TODO(edisonn): report default one?
}
2013-08-14 18:26:20 +00:00
if ( ! dict - > hasData ( SkPdfNativeObject : : kFont_Data ) ) {
dict - > setData ( fontFromPdfDictionaryOnce ( doc , dict ) , SkPdfNativeObject : : kFont_Data ) ;
2013-07-10 17:09:50 +00:00
}
2013-08-14 18:26:20 +00:00
return ( SkPdfFont * ) dict - > data ( SkPdfNativeObject : : kFont_Data ) ;
2013-07-10 17:09:50 +00:00
}
2013-08-14 18:26:20 +00:00
SkPdfType0Font * SkPdfFont : : fontFromType0FontDictionary ( SkPdfNativeDoc * doc , SkPdfType0FontDictionary * dict ) {
2013-06-21 21:43:09 +00:00
if ( dict = = NULL ) {
return NULL ; // default one?
}
2013-07-10 17:09:50 +00:00
return new SkPdfType0Font ( doc , dict ) ;
2013-06-21 21:43:09 +00:00
}
2013-08-14 18:26:20 +00:00
SkPdfType1Font * SkPdfFont : : fontFromType1FontDictionary ( SkPdfNativeDoc * doc , SkPdfType1FontDictionary * dict ) {
2013-06-21 21:43:09 +00:00
if ( dict = = NULL ) {
return NULL ; // default one?
}
2013-07-10 17:09:50 +00:00
return new SkPdfType1Font ( doc , dict ) ;
2013-06-21 21:43:09 +00:00
}
2013-08-14 18:26:20 +00:00
SkPdfType3Font * SkPdfFont : : fontFromType3FontDictionary ( SkPdfNativeDoc * doc , SkPdfType3FontDictionary * dict ) {
2013-06-21 21:43:09 +00:00
if ( dict = = NULL ) {
return NULL ; // default one?
}
2013-06-25 20:45:40 +00:00
2013-07-10 17:09:50 +00:00
return new SkPdfType3Font ( doc , dict ) ;
2013-06-21 21:43:09 +00:00
}
2013-08-14 18:26:20 +00:00
SkPdfTrueTypeFont * SkPdfFont : : fontFromTrueTypeFontDictionary ( SkPdfNativeDoc * doc , SkPdfTrueTypeFontDictionary * dict ) {
2013-06-21 21:43:09 +00:00
if ( dict = = NULL ) {
return NULL ; // default one?
}
2013-07-10 17:09:50 +00:00
return new SkPdfTrueTypeFont ( doc , dict ) ;
2013-06-21 21:43:09 +00:00
}
2013-08-14 18:26:20 +00:00
SkPdfMultiMasterFont * SkPdfFont : : fontFromMultiMasterFontDictionary ( SkPdfNativeDoc * doc , SkPdfMultiMasterFontDictionary * dict ) {
2013-06-21 21:43:09 +00:00
if ( dict = = NULL ) {
return NULL ; // default one?
}
2013-07-10 17:09:50 +00:00
return new SkPdfMultiMasterFont ( doc , dict ) ;
2013-06-21 21:43:09 +00:00
}
2013-08-14 18:26:20 +00:00
static int skstoi ( const SkPdfNativeObject * str ) {
2013-07-10 17:09:50 +00:00
// TODO(edisonn): report err of it is not a (hex) string
2013-06-21 21:43:09 +00:00
int ret = 0 ;
2013-07-29 19:10:58 +00:00
for ( unsigned int i = 0 ; i < str - > lenstr ( ) ; i + + ) {
2013-07-02 22:42:53 +00:00
ret = ( ret < < 8 ) + ( ( unsigned char * ) str - > c_str ( ) ) [ i ] ;
2013-06-21 21:43:09 +00:00
}
2013-07-25 22:03:22 +00:00
// TODO(edisonn): character larger than 0x0000ffff not supported right now.
return ret & 0x0000ffff ;
2013-06-21 21:43:09 +00:00
}
2013-07-10 17:09:50 +00:00
# define tokenIsKeyword(token,keyword) (token.fType == kKeyword_TokenType && token.fKeywordLength==sizeof(keyword)-1 && strncmp(token.fKeyword, keyword, sizeof(keyword)-1) == 0)
2013-08-14 18:26:20 +00:00
SkPdfToUnicode : : SkPdfToUnicode ( SkPdfNativeDoc * parsed , SkPdfStream * stream ) : fParsed ( parsed ) {
2013-06-21 21:43:09 +00:00
fCMapEncoding = NULL ;
fCMapEncodingFlag = NULL ;
2013-06-25 20:45:40 +00:00
if ( stream ) {
2013-07-23 17:43:18 +00:00
// Since font will be cached, the font has to sit in the per doc allocator, not to be
// freed after the page is done drawing.
SkPdfNativeTokenizer * tokenizer = fParsed - > tokenizerOfStream ( stream , parsed - > allocator ( ) ) ;
2013-06-21 21:43:09 +00:00
PdfToken token ;
fCMapEncoding = new unsigned short [ 256 * 256 ] ;
fCMapEncodingFlag = new unsigned char [ 256 * 256 ] ;
for ( int i = 0 ; i < 256 * 256 ; i + + ) {
fCMapEncoding [ i ] = i ;
fCMapEncodingFlag [ i ] = 0 ;
}
// TODO(edisonn): deal with multibyte character, or longer strings.
// Ritght now we deal with up 2 characters, e.g. <0020> but not longer like <00660066006C>
//2 beginbfrange
//<0000> <005E> <0020>
//<005F> <0061> [<00660066> <00660069> <00660066006C>]
2013-07-02 22:42:53 +00:00
while ( tokenizer - > readToken ( & token ) ) {
2013-06-21 21:43:09 +00:00
2013-07-10 17:09:50 +00:00
// TODO(edisonn): perf, macro that would make equal first for token.fKeywordLength with sizeof(keyword), instead od strlen, make sure it is keyword, not a char*
if ( tokenIsKeyword ( token , " begincodespacerange " ) ) {
while ( tokenizer - > readToken ( & token ) & & ! tokenIsKeyword ( token , " endcodespacerange " ) ) {
2013-07-02 22:42:53 +00:00
// tokenizer->PutBack(token);
// tokenizer->readToken(&token);
2013-06-21 21:43:09 +00:00
// TODO(edisonn): check token type! ignore/report errors.
2013-07-10 17:09:50 +00:00
int start = skstoi ( token . fObject ) ;
2013-07-02 22:42:53 +00:00
tokenizer - > readToken ( & token ) ;
2013-07-10 17:09:50 +00:00
int end = skstoi ( token . fObject ) ;
2013-06-21 21:43:09 +00:00
for ( int i = start ; i < = end ; i + + ) {
fCMapEncodingFlag [ i ] | = 1 ;
}
}
}
2013-07-10 17:09:50 +00:00
if ( tokenIsKeyword ( token , " beginbfchar " ) ) {
while ( tokenizer - > readToken ( & token ) & & ! tokenIsKeyword ( token , " endbfchar " ) ) {
2013-07-02 22:42:53 +00:00
// tokenizer->PutBack(token);
// tokenizer->readToken(&token);
2013-07-10 17:09:50 +00:00
int from = skstoi ( token . fObject ) ;
2013-07-02 22:42:53 +00:00
tokenizer - > readToken ( & token ) ;
2013-07-10 17:09:50 +00:00
int to = skstoi ( token . fObject ) ;
2013-06-21 21:43:09 +00:00
fCMapEncodingFlag [ from ] | = 2 ;
fCMapEncoding [ from ] = to ;
}
}
2013-07-10 17:09:50 +00:00
if ( tokenIsKeyword ( token , " beginbfrange " ) ) {
while ( tokenizer - > readToken ( & token ) & & ! tokenIsKeyword ( token , " endbfrange " ) ) {
2013-07-02 22:42:53 +00:00
// tokenizer->PutBack(token);
// tokenizer->readToken(&token);
2013-07-10 17:09:50 +00:00
int start = skstoi ( token . fObject ) ;
2013-07-02 22:42:53 +00:00
tokenizer - > readToken ( & token ) ;
2013-07-10 17:09:50 +00:00
int end = skstoi ( token . fObject ) ;
2013-06-21 21:43:09 +00:00
2013-07-02 22:42:53 +00:00
tokenizer - > readToken ( & token ) ; // [ or just an array directly?
// tokenizer->PutBack(token);
2013-06-21 21:43:09 +00:00
2013-07-10 17:09:50 +00:00
// TODO(edisonn): read spec: any string or only hex string?
if ( token . fType = = kObject_TokenType & & token . fObject - > isAnyString ( ) ) {
2013-07-02 22:42:53 +00:00
// tokenizer->readToken(&token);
2013-07-10 17:09:50 +00:00
int value = skstoi ( token . fObject ) ;
2013-06-21 21:43:09 +00:00
for ( int i = start ; i < = end ; i + + ) {
fCMapEncodingFlag [ i ] | = 2 ;
fCMapEncoding [ i ] = value ;
value + + ;
// if i != end, verify last byte id not if, ignore/report error
}
// read one string
2013-07-10 17:09:50 +00:00
} else if ( token . fType = = kObject_TokenType & & token . fObject - > isArray ( ) ) {
2013-07-02 22:42:53 +00:00
// tokenizer->readToken(&token);
2013-07-10 17:09:50 +00:00
for ( unsigned int i = 0 ; i < token . fObject - > size ( ) ; i + + ) {
2013-06-21 21:43:09 +00:00
fCMapEncodingFlag [ start + i ] | = 2 ;
2013-07-10 17:09:50 +00:00
fCMapEncoding [ start + i ] = skstoi ( ( * token . fObject ) [ i ] ) ;
2013-06-21 21:43:09 +00:00
}
// read array
}
//fCMapEncodingFlag[from] = 1;
//fCMapEncoding[from] = to;
}
}
}
}
}
2013-06-25 20:45:40 +00:00
2013-08-14 18:26:20 +00:00
SkPdfType0Font : : SkPdfType0Font ( SkPdfNativeDoc * doc , SkPdfType0FontDictionary * dict ) {
2013-07-10 17:09:50 +00:00
fBaseFont = fontFromName ( doc , dict , dict - > BaseFont ( doc ) . c_str ( ) ) ;
2013-06-25 20:45:40 +00:00
fEncoding = NULL ;
if ( dict - > has_Encoding ( ) ) {
2013-07-10 17:09:50 +00:00
if ( dict - > isEncodingAName ( doc ) ) {
fEncoding = SkPdfEncoding : : fromName ( dict - > getEncodingAsName ( doc ) . c_str ( ) ) ;
} else if ( dict - > isEncodingAStream ( doc ) ) {
2013-06-25 20:45:40 +00:00
//fEncoding = loadEncodingFromStream(dict->getEncodingAsStream());
} else {
// TODO(edisonn): error ... warning .. assert?
}
}
if ( dict - > has_ToUnicode ( ) ) {
2013-07-10 17:09:50 +00:00
fToUnicode = new SkPdfToUnicode ( doc , dict - > ToUnicode ( doc ) ) ;
2013-06-25 20:45:40 +00:00
}
}
2013-08-16 15:05:08 +00:00
SkTDict < SkPdfEncoding * > & getStandardEncodings ( ) {
static SkTDict < SkPdfEncoding * > encodings ( 10 ) ;
if ( encodings . count ( ) = = 0 ) {
encodings . set ( " Identity-H " , SkPdfIdentityHEncoding : : instance ( ) ) ;
2013-06-25 20:45:40 +00:00
}
return encodings ;
}
SkPdfEncoding * SkPdfEncoding : : fromName ( const char * name ) {
2013-08-16 15:05:08 +00:00
SkPdfEncoding * encoding = NULL ;
if ( ! getStandardEncodings ( ) . find ( name , & encoding ) ) {
// TODO(edisonn): if the function return false, and we a guaranteed that the value is not
// changed, delete this set to null
encoding = NULL ;
}
2013-06-25 20:45:40 +00:00
# ifdef PDF_TRACE
if ( encoding = = NULL ) {
printf ( " Encoding not found: %s \n " , name ) ;
}
# endif
return encoding ;
}