1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 
27 #include <tools/debug.hxx>
28 
29 #include <fontsubset.hxx>
30 #include <sft.hxx>
31 
32 // ====================================================================
33 
FontSubsetInfo()34 FontSubsetInfo::FontSubsetInfo()
35 :	m_nAscent( 0)
36 ,	m_nDescent( 0)
37 ,	m_nCapHeight( 0)
38 ,	m_nFontType( FontSubsetInfo::NO_FONT)
39 ,	mpInFontBytes( NULL)
40 ,	mnInByteLength( 0)
41 ,	meInFontType( FontSubsetInfo::NO_FONT)
42 ,	mpSftTTFont( NULL)
43 {}
44 
45 // --------------------------------------------------------------------
46 
~FontSubsetInfo()47 FontSubsetInfo::~FontSubsetInfo()
48 {}
49 
50 // --------------------------------------------------------------------
51 
52 // prepare subsetting for fonts where the input font file is mapped
LoadFont(FontSubsetInfo::FontType eInFontType,const unsigned char * pInFontBytes,int nInByteLength)53 bool FontSubsetInfo::LoadFont(
54 	FontSubsetInfo::FontType eInFontType,
55 	const unsigned char* pInFontBytes, int nInByteLength)
56 {
57 	DBG_ASSERT( (mpSftTTFont == NULL), "Subset from SFT and from mapped font-file requested");
58 	meInFontType = eInFontType;
59 	mpInFontBytes = pInFontBytes;
60 	mnInByteLength = nInByteLength;
61 	return (mnInByteLength > 0);
62 }
63 
64 // --------------------------------------------------------------------
65 
66 // prepare subsetting for fonts that are known to the SFT-parser
LoadFont(vcl::_TrueTypeFont * pSftTTFont)67 bool FontSubsetInfo::LoadFont( vcl::_TrueTypeFont* pSftTTFont )
68 {
69 	DBG_ASSERT( (mpInFontBytes == NULL), "Subset from SFT and from mapped font-file requested");
70 	mpSftTTFont = pSftTTFont;
71 	meInFontType = ANY_SFNT;
72 	return (mpSftTTFont == NULL);
73 }
74 
75 // --------------------------------------------------------------------
76 
CreateFontSubset(int nReqFontTypeMask,FILE * pOutFile,const char * pReqFontName,const sal_GlyphId * pReqGlyphIds,const sal_uInt8 * pReqEncodedIds,int nReqGlyphCount,sal_Int32 * pOutGlyphWidths)77 bool FontSubsetInfo::CreateFontSubset(
78 	int nReqFontTypeMask,
79 	FILE* pOutFile, const char* pReqFontName,
80 	const sal_GlyphId* pReqGlyphIds, const sal_uInt8* pReqEncodedIds, int nReqGlyphCount,
81 	sal_Int32* pOutGlyphWidths)
82 {
83 	// prepare request details needed by all underlying subsetters
84 	mnReqFontTypeMask = nReqFontTypeMask;
85 	mpOutFile		= pOutFile;
86 	mpReqFontName	= pReqFontName;
87 	mpReqGlyphIds	= pReqGlyphIds;
88 	mpReqEncodedIds	= pReqEncodedIds;
89 	mnReqGlyphCount	= nReqGlyphCount;
90 
91 	// TODO: move the glyphid/encid/notdef reshuffling from the callers to here
92 
93 	// dispatch to underlying subsetters
94 	bool bOK = false;
95 
96 	// TODO: better match available input-type to possible subset-types
97 	switch( meInFontType) {
98 	case SFNT_TTF:
99 	case SFNT_CFF:
100 	case ANY_SFNT:
101 		bOK = CreateFontSubsetFromSfnt( pOutGlyphWidths);
102 		break;
103 	case CFF_FONT:
104 		bOK = CreateFontSubsetFromCff( pOutGlyphWidths);
105 		break;
106 	case TYPE1_PFA:
107 	case TYPE1_PFB:
108 	case ANY_TYPE1:
109 		bOK = CreateFontSubsetFromType1( pOutGlyphWidths);
110 		break;
111 		// fall trough
112 	case NO_FONT:
113 		// fall trough
114 	default:
115 		DBG_ERROR( "unhandled type in CreateFontSubset()");
116 		break;
117 	}
118 
119 	return bOK;
120 }
121 
122 // --------------------------------------------------------------------
123 
124 // TODO: move function to sft.cxx to replace dummy implementation
CreateFontSubsetFromSfnt(sal_Int32 * pOutGlyphWidths)125 bool FontSubsetInfo::CreateFontSubsetFromSfnt( sal_Int32* pOutGlyphWidths )
126 {
127 	// handle SFNT_CFF fonts
128 	int nCffLength = 0;
129 	const sal_uInt8* pCffBytes = NULL;
130 	if( GetSfntTable( mpSftTTFont, O_CFF, &pCffBytes, &nCffLength))
131 	{
132 		LoadFont( CFF_FONT, pCffBytes, nCffLength);
133 		const bool bOK = CreateFontSubsetFromCff( pOutGlyphWidths);
134 		return bOK;
135 	}
136 
137 	// handle SFNT_TTF fonts
138 	// by forwarding the subset request to AG's sft subsetter
139 #if 1 // TODO: remove conversion tp 16bit glyphids when sft-subsetter has been updated
140 	sal_uInt16 aShortGlyphIds[256];
141 	for( int i = 0; i < mnReqGlyphCount; ++i)
142 		aShortGlyphIds[i] = (sal_uInt16)mpReqGlyphIds[i];
143 	// remove const_cast when sft-subsetter is const-correct
144 	sal_uInt8* pEncArray = const_cast<sal_uInt8*>( mpReqEncodedIds );
145 #endif
146 	int nSFTErr = vcl::SF_BADARG;
147 	if( (mnReqFontTypeMask & TYPE42_FONT) != 0 )
148 	{
149 		nSFTErr = CreateT42FromTTGlyphs( mpSftTTFont, mpOutFile, mpReqFontName,
150 			aShortGlyphIds, pEncArray, mnReqGlyphCount );
151 	}
152 	else if( (mnReqFontTypeMask & TYPE3_FONT) != 0 )
153 	{
154 		nSFTErr = CreateT3FromTTGlyphs( mpSftTTFont, mpOutFile, mpReqFontName,
155 			aShortGlyphIds, pEncArray, mnReqGlyphCount,
156             		0 /* 0 = horizontal, 1 = vertical */ );
157 	}
158 	else if( (mnReqFontTypeMask & SFNT_TTF) != 0 )
159 	{
160 		// TODO: use CreateTTFromTTGlyphs()
161 		// TODO: move functionality from callers here
162 	}
163 
164 	return (nSFTErr != vcl::SF_OK);
165 }
166 
167 // --------------------------------------------------------------------
168 
169 // TODO: replace dummy implementation
CreateFontSubsetFromType1(sal_Int32 * pOutGlyphWidths)170 bool FontSubsetInfo::CreateFontSubsetFromType1( sal_Int32* pOutGlyphWidths)
171 {
172 #if 0
173 	// TODO: replace dummy implementation when someone needs this
174 #else
175 	(void)pOutGlyphWidths;
176 	fprintf(stderr,"CreateFontSubsetFromType1: replace dummy implementation\n");
177 #endif
178 	return false;
179 }
180 
181 // ====================================================================
182 
183