1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <tools/debug.hxx> 32 33 #include <fontsubset.hxx> 34 #include <sft.hxx> 35 36 // ==================================================================== 37 38 FontSubsetInfo::FontSubsetInfo() 39 : m_nAscent( 0) 40 , m_nDescent( 0) 41 , m_nCapHeight( 0) 42 , m_nFontType( FontSubsetInfo::NO_FONT) 43 , mpInFontBytes( NULL) 44 , mnInByteLength( 0) 45 , meInFontType( FontSubsetInfo::NO_FONT) 46 , mpSftTTFont( NULL) 47 {} 48 49 // -------------------------------------------------------------------- 50 51 FontSubsetInfo::~FontSubsetInfo() 52 {} 53 54 // -------------------------------------------------------------------- 55 56 // prepare subsetting for fonts where the input font file is mapped 57 bool FontSubsetInfo::LoadFont( 58 FontSubsetInfo::FontType eInFontType, 59 const unsigned char* pInFontBytes, int nInByteLength) 60 { 61 DBG_ASSERT( (mpSftTTFont == NULL), "Subset from SFT and from mapped font-file requested"); 62 meInFontType = eInFontType; 63 mpInFontBytes = pInFontBytes; 64 mnInByteLength = nInByteLength; 65 return (mnInByteLength > 0); 66 } 67 68 // -------------------------------------------------------------------- 69 70 // prepare subsetting for fonts that are known to the SFT-parser 71 bool FontSubsetInfo::LoadFont( vcl::_TrueTypeFont* pSftTTFont ) 72 { 73 DBG_ASSERT( (mpInFontBytes == NULL), "Subset from SFT and from mapped font-file requested"); 74 mpSftTTFont = pSftTTFont; 75 meInFontType = ANY_SFNT; 76 return (mpSftTTFont == NULL); 77 } 78 79 // -------------------------------------------------------------------- 80 81 bool FontSubsetInfo::CreateFontSubset( 82 int nReqFontTypeMask, 83 FILE* pOutFile, const char* pReqFontName, 84 const long* pReqGlyphIds, const sal_uInt8* pReqEncodedIds, int nReqGlyphCount, 85 sal_Int32* pOutGlyphWidths) 86 { 87 // prepare request details needed by all underlying subsetters 88 mnReqFontTypeMask = nReqFontTypeMask; 89 mpOutFile = pOutFile; 90 mpReqFontName = pReqFontName; 91 mpReqGlyphIds = pReqGlyphIds; 92 mpReqEncodedIds = pReqEncodedIds; 93 mnReqGlyphCount = nReqGlyphCount; 94 95 // TODO: move the glyphid/encid/notdef reshuffling from the callers to here 96 97 // dispatch to underlying subsetters 98 bool bOK = false; 99 100 // TODO: better match available input-type to possible subset-types 101 switch( meInFontType) { 102 case SFNT_TTF: 103 case SFNT_CFF: 104 case ANY_SFNT: 105 bOK = CreateFontSubsetFromSfnt( pOutGlyphWidths); 106 break; 107 case CFF_FONT: 108 bOK = CreateFontSubsetFromCff( pOutGlyphWidths); 109 break; 110 case TYPE1_PFA: 111 case TYPE1_PFB: 112 case ANY_TYPE1: 113 bOK = CreateFontSubsetFromType1( pOutGlyphWidths); 114 break; 115 // fall trough 116 case NO_FONT: 117 // fall trough 118 default: 119 DBG_ERROR( "unhandled type in CreateFontSubset()"); 120 break; 121 } 122 123 return bOK; 124 } 125 126 // -------------------------------------------------------------------- 127 128 // TODO: move function to sft.cxx to replace dummy implementation 129 bool FontSubsetInfo::CreateFontSubsetFromSfnt( sal_Int32* pOutGlyphWidths ) 130 { 131 // handle SFNT_CFF fonts 132 int nCffLength = 0; 133 const sal_uInt8* pCffBytes = NULL; 134 if( GetSfntTable( mpSftTTFont, O_CFF, &pCffBytes, &nCffLength)) 135 { 136 LoadFont( CFF_FONT, pCffBytes, nCffLength); 137 const bool bOK = CreateFontSubsetFromCff( pOutGlyphWidths); 138 return bOK; 139 } 140 141 // handle SFNT_TTF fonts 142 // by forwarding the subset request to AG's sft subsetter 143 #if 1 // TODO: remove conversion tp 16bit glyphids when sft-subsetter has been updated 144 sal_uInt16 aShortGlyphIds[256]; 145 for( int i = 0; i < mnReqGlyphCount; ++i) 146 aShortGlyphIds[i] = (sal_uInt16)mpReqGlyphIds[i]; 147 // remove const_cast when sft-subsetter is const-correct 148 sal_uInt8* pEncArray = const_cast<sal_uInt8*>( mpReqEncodedIds ); 149 #endif 150 int nSFTErr = vcl::SF_BADARG; 151 if( (mnReqFontTypeMask & TYPE42_FONT) != 0 ) 152 { 153 nSFTErr = CreateT42FromTTGlyphs( mpSftTTFont, mpOutFile, mpReqFontName, 154 aShortGlyphIds, pEncArray, mnReqGlyphCount ); 155 } 156 else if( (mnReqFontTypeMask & TYPE3_FONT) != 0 ) 157 { 158 nSFTErr = CreateT3FromTTGlyphs( mpSftTTFont, mpOutFile, mpReqFontName, 159 aShortGlyphIds, pEncArray, mnReqGlyphCount, 160 0 /* 0 = horizontal, 1 = vertical */ ); 161 } 162 else if( (mnReqFontTypeMask & SFNT_TTF) != 0 ) 163 { 164 // TODO: use CreateTTFromTTGlyphs() 165 // TODO: move functionality from callers here 166 } 167 168 return (nSFTErr != vcl::SF_OK); 169 } 170 171 // -------------------------------------------------------------------- 172 173 // TODO: replace dummy implementation 174 bool FontSubsetInfo::CreateFontSubsetFromType1( sal_Int32* pOutGlyphWidths) 175 { 176 #if 0 177 // TODO: replace dummy implementation when someone needs this 178 #else 179 (void)pOutGlyphWidths; 180 fprintf(stderr,"CreateFontSubsetFromType1: replace dummy implementation\n"); 181 #endif 182 return false; 183 } 184 185 // ==================================================================== 186 187