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