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