コード例 #1
0
EStatusCode CFFEmbeddedFontWriter::WriteCharsets(const UIntVector& inSubsetGlyphIDs,
													UShortVector* inCIDMapping)
{
	// since this is a subset the chances that i'll get a defult charset are 0.
	// hence i'll always do some charset. and using format 0 !!1
	UIntVector::const_iterator it = inSubsetGlyphIDs.begin();
	++it; // skip the 0

	mCharsetPosition = mFontFileStream.GetCurrentPosition();

	mPrimitivesWriter.WriteCard8(0);
	if(mIsCID && inCIDMapping)
	{
		UShortVector::const_iterator itCIDs = inCIDMapping->begin();
		++itCIDs;
		for(; it != inSubsetGlyphIDs.end(); ++it,++itCIDs)
			mPrimitivesWriter.WriteSID(*itCIDs);

	}
	else
	{
		// note that this also works for CIDs! cause in this case the SIDs are actually
		// CIDs
		for(; it != inSubsetGlyphIDs.end(); ++it)
			mPrimitivesWriter.WriteSID(mOpenTypeInput.mCFF.GetGlyphSID(0,*it));
	}
	return mPrimitivesWriter.GetInternalState();
}
コード例 #2
0
EStatusCode CFFEmbeddedFontWriter::AddDependentGlyphs(UIntVector& ioSubsetGlyphIDs)
{
	EStatusCode status = PDFHummus::eSuccess;
	UIntSet glyphsSet;
	UIntVector::iterator it = ioSubsetGlyphIDs.begin();
	bool hasCompositeGlyphs = false;

	for(;it != ioSubsetGlyphIDs.end() && PDFHummus::eSuccess == status; ++it)
	{
		bool localHasCompositeGlyphs;
		status = AddComponentGlyphs(*it,glyphsSet,localHasCompositeGlyphs);
		hasCompositeGlyphs |= localHasCompositeGlyphs;
	}

	if(hasCompositeGlyphs)
	{
		UIntSet::iterator itNewGlyphs;

		for(it = ioSubsetGlyphIDs.begin();it != ioSubsetGlyphIDs.end(); ++it)
			glyphsSet.insert(*it);

		ioSubsetGlyphIDs.clear();
		for(itNewGlyphs = glyphsSet.begin(); itNewGlyphs != glyphsSet.end(); ++itNewGlyphs)
			ioSubsetGlyphIDs.push_back(*itNewGlyphs);
		
		sort(ioSubsetGlyphIDs.begin(),ioSubsetGlyphIDs.end());
	}	
	return status;
}
コード例 #3
0
static UIntVector GetOrderedKeys(const UIntAndGlyphEncodingInfoVector& inMap)
{
	UIntVector result;
	for(UIntAndGlyphEncodingInfoVector::const_iterator it = inMap.begin(); it != inMap.end(); ++it)
		result.push_back(it->first);
	sort(result.begin(),result.end());
	return result;
}
コード例 #4
0
void Type1ToCFFEmbeddedFontWriter::TranslateFromFreeTypeToType1(FreeTypeFaceWrapper& inFontInfo,
																const UIntVector& inSubsetGlyphIDs,
																StringVector& outGlyphNames)
{
	UIntVector::const_iterator it = inSubsetGlyphIDs.begin();
	
    for(; it != inSubsetGlyphIDs.end(); ++it)
        outGlyphNames.push_back(inFontInfo.GetGlyphName(*it));
    
}
コード例 #5
0
EStatusCode CFFEmbeddedFontWriter::WriteCharStrings(const UIntVector& inSubsetGlyphIDs)
{
	/*
		1. build the charstrings data, looping the glyphs charstrings and writing a flattened
		   version of each charstring
		2. write the charstring index based on offsets inside the data (size should be according to the max)
		3. copy the data into the stream
	*/


	unsigned long* offsets = new unsigned long[inSubsetGlyphIDs.size() + 1];
	MyStringBuf charStringsData;
	OutputStringBufferStream charStringsDataWriteStream(&charStringsData);
	CharStringType2Flattener charStringFlattener;
	UIntVector::const_iterator itGlyphs = inSubsetGlyphIDs.begin();
	EStatusCode status = PDFHummus::eSuccess;

	do
	{
		unsigned short i=0;
		for(; itGlyphs != inSubsetGlyphIDs.end() && PDFHummus::eSuccess == status; ++itGlyphs,++i)
		{
			offsets[i] = (unsigned long)charStringsDataWriteStream.GetCurrentPosition();
			status = charStringFlattener.WriteFlattenedGlyphProgram(	0,
																		*itGlyphs,
																		&(mOpenTypeInput.mCFF),
																		&charStringsDataWriteStream);
		}
		if(status != PDFHummus::eSuccess)
			break;

		offsets[i] = (unsigned long)charStringsDataWriteStream.GetCurrentPosition();

		charStringsData.pubseekoff(0,std::ios_base::beg);

		// write index section
		mCharStringPosition = mFontFileStream.GetCurrentPosition();
		Byte sizeOfOffset = GetMostCompressedOffsetSize(offsets[i] + 1);
		mPrimitivesWriter.WriteCard16((unsigned short)inSubsetGlyphIDs.size());
		mPrimitivesWriter.WriteOffSize(sizeOfOffset);
		mPrimitivesWriter.SetOffSize(sizeOfOffset);
		for(i=0;i<=inSubsetGlyphIDs.size();++i)
			mPrimitivesWriter.WriteOffset(offsets[i] + 1);

		// Write data
		InputStringBufferStream charStringsDataReadStream(&charStringsData);
		OutputStreamTraits streamCopier(&mFontFileStream);
		status = streamCopier.CopyToOutputStream(&charStringsDataReadStream);
		if(status != PDFHummus::eSuccess)
			break;
	}while(false);

	delete[] offsets;
	return status;
}
コード例 #6
0
EStatusCode TrueTypeEmbeddedFontWriter::WriteGlyf(const UIntVector& inSubsetGlyphIDs,unsigned long* inLocaTable)
{
	// k. write the glyphs table. you only need to write the glyphs you are actually using.
	// while at it...update the locaTable

	TableEntry* tableEntry = mTrueTypeInput.GetTableEntry("glyf");
	LongFilePositionType startTableOffset = mFontFileStream.GetCurrentPosition();
	UIntVector::const_iterator it = inSubsetGlyphIDs.begin();
	OutputStreamTraits streamCopier(&mFontFileStream);
	unsigned short glyphIndex,previousGlyphIndexEnd = 0;
	inLocaTable[0] = 0;
	EStatusCode status = eSuccess;

	for(;it != inSubsetGlyphIDs.end() && eSuccess == status; ++it)
	{
		glyphIndex = *it;
		if(glyphIndex >= mTrueTypeInput.mMaxp.NumGlyphs)
		{
			TRACE_LOG2("TrueTypeEmbeddedFontWriter::WriteGlyf, error, requested glyph index %ld is larger than the maximum glyph index for this font which is %ld. ",glyphIndex,mTrueTypeInput.mMaxp.NumGlyphs-1);
			status = eFailure;
			break;
		}

		for(unsigned short i= previousGlyphIndexEnd + 1; i<=glyphIndex;++i)
			inLocaTable[i] = inLocaTable[previousGlyphIndexEnd];
		if(mTrueTypeInput.mGlyf[glyphIndex] != NULL)
		{
			mTrueTypeFile.GetInputStream()->SetPosition(tableEntry->Offset + 
															mTrueTypeInput.mLoca[glyphIndex]);
			streamCopier.CopyToOutputStream(mTrueTypeFile.GetInputStream(),
				mTrueTypeInput.mLoca[(glyphIndex) + 1] - mTrueTypeInput.mLoca[glyphIndex]);
		}
		inLocaTable[glyphIndex + 1] = (unsigned long)(mFontFileStream.GetCurrentPosition() - startTableOffset);
		previousGlyphIndexEnd = glyphIndex + 1;
	}

	LongFilePositionType endOfTable = mFontFileStream.GetCurrentPosition();
	mPrimitivesWriter.PadTo4();
	LongFilePositionType endOfStream = mFontFileStream.GetCurrentPosition();

	// write table entry data, which includes movement
	WriteTableEntryData(mGLYFEntryWritingOffset,
						startTableOffset,
						(unsigned long)(endOfTable - startTableOffset));

	// restore position to end of stream
	mFontFileStream.SetPosition(endOfStream); 

	return mPrimitivesWriter.GetInternalState();	
}
コード例 #7
0
void TrueTypeEmbeddedFontWriter::AddDependentGlyphs(UIntVector& ioSubsetGlyphIDs)
{
	UIntSet glyphsSet;
	UIntVector::iterator it = ioSubsetGlyphIDs.begin();
	bool hasCompositeGlyphs = false;

	for(;it != ioSubsetGlyphIDs.end(); ++it)
		hasCompositeGlyphs |= AddComponentGlyphs(*it,glyphsSet);

	if(hasCompositeGlyphs)
	{
		UIntSet::iterator itNewGlyphs;

		for(it = ioSubsetGlyphIDs.begin();it != ioSubsetGlyphIDs.end(); ++it)
			glyphsSet.insert(*it);

		ioSubsetGlyphIDs.clear();
		for(itNewGlyphs = glyphsSet.begin(); itNewGlyphs != glyphsSet.end(); ++itNewGlyphs)
			ioSubsetGlyphIDs.push_back(*itNewGlyphs);
		
		sort(ioSubsetGlyphIDs.begin(),ioSubsetGlyphIDs.end());
	}
}
コード例 #8
0
EStatusCode CFFEmbeddedFontWriter::WriteFDSelect(const UIntVector& inSubsetGlyphIDs,const FontDictInfoToByteMap& inNewFontDictsIndexes)
{
	// always write format 3. cause at most cases the FD dicts count will be so low that it'd
	// take a bloody mircale for no repeats to occur.
	UIntVector::const_iterator itGlyphs = inSubsetGlyphIDs.begin();


	mFDSelectPosition = mFontFileStream.GetCurrentPosition();
	mPrimitivesWriter.WriteCard8(3);

	LongFilePositionType rangesCountPosition = mFontFileStream.GetCurrentPosition();
	mPrimitivesWriter.WriteCard16(1); // temporary. will get back to this later

	unsigned short rangesCount = 1;
	Byte currentFD,newFD;
	unsigned short glyphIndex = 1;
	FontDictInfoToByteMap::const_iterator itNewIndex = 
		inNewFontDictsIndexes.find(mOpenTypeInput.mCFF.mTopDictIndex[0].mFDSelect[*itGlyphs]);
	
	// k. seems like i probably just imagine exceptions here. i guess there must
	// be a proper FDSelect with FDs for all...so i'm defaulting to some 0
	currentFD = (itNewIndex == inNewFontDictsIndexes.end() ? 0:itNewIndex->second);
	mPrimitivesWriter.WriteCard16(0);
	mPrimitivesWriter.WriteCard8(currentFD);
	++itGlyphs;

	for(; itGlyphs != inSubsetGlyphIDs.end(); ++itGlyphs,++glyphIndex)
	{
		itNewIndex = 
				inNewFontDictsIndexes.find(mOpenTypeInput.mCFF.mTopDictIndex[0].mFDSelect[*itGlyphs]);
		newFD = (itNewIndex == inNewFontDictsIndexes.end() ? 0:itNewIndex->second);
		if(newFD != currentFD)
		{
			currentFD = newFD;
			mPrimitivesWriter.WriteCard16(glyphIndex);
			mPrimitivesWriter.WriteCard8(currentFD);
			++rangesCount;
		}
	}
	mPrimitivesWriter.WriteCard16((unsigned short)inSubsetGlyphIDs.size());
	// go back to ranges count if not equal to what's already written
	if(rangesCount != 1)
	{
		LongFilePositionType currentPosition = mFontFileStream.GetCurrentPosition();
		mFontFileStream.SetPosition(rangesCountPosition);
		mPrimitivesWriter.WriteCard16(rangesCount);
		mFontFileStream.SetPosition(currentPosition);
	}
	return mPrimitivesWriter.GetInternalState();
}
コード例 #9
0
void CFFEmbeddedFontWriter::DetermineFDArrayIndexes(const UIntVector& inSubsetGlyphIDs,FontDictInfoToByteMap& outNewFontDictsIndexes)
{
	UIntVector::const_iterator itGlyphs = inSubsetGlyphIDs.begin();
	FontDictInfoSet fontDictInfos;

	for(; itGlyphs != inSubsetGlyphIDs.end(); ++itGlyphs)
		if(mOpenTypeInput.mCFF.mTopDictIndex[0].mFDSelect[*itGlyphs])
			fontDictInfos.insert(mOpenTypeInput.mCFF.mTopDictIndex[0].mFDSelect[*itGlyphs]);

	FontDictInfoSet::iterator itFontInfos;
	Byte i=0;

	for(itFontInfos = fontDictInfos.begin(); itFontInfos != fontDictInfos.end(); ++itFontInfos,++i)
		outNewFontDictsIndexes.insert(FontDictInfoToByteMap::value_type(*itFontInfos,i));
}
コード例 #10
0
EStatusCode CFFEmbeddedFontWriter::WriteEncodings(const UIntVector& inSubsetGlyphIDs)
{
	// if it's a CID. don't bother with encodings (marks as 0)
	if(mIsCID)
	{
		mEncodingPosition = 0;
		return PDFHummus::eSuccess;
	}

	// not CID, write encoding, according to encoding values from the original font
	EncodingsInfo* encodingInfo = mOpenTypeInput.mCFF.mTopDictIndex[0].mEncoding;
	if(encodingInfo->mEncodingStart <= 1)
	{
		mEncodingPosition = encodingInfo->mEncodingStart;
		return PDFHummus::eSuccess;
	}
	else
	{	
		// original font had custom encoding, let's subset it according to just the glyphs we 
		// actually have. but cause i'm lazy i'll just do the first format.

		// figure out if we got supplements
		UIntVector::const_iterator it = inSubsetGlyphIDs.begin();
		ByteAndUShortList supplements;

		for(; it != inSubsetGlyphIDs.end();++it)
		{
			// don't be confused! the supplements is by SID! not GID!
			unsigned short sid = mOpenTypeInput.mCFF.GetGlyphSID(0,*it);

			UShortToByteList::iterator itSupplements = encodingInfo->mSupplements.find(sid);
			if(itSupplements != encodingInfo->mSupplements.end())
			{
				ByteList::iterator itMoreEncoding = itSupplements->second.begin();
				for(; itMoreEncoding != itSupplements->second.end(); ++itMoreEncoding)
					supplements.push_back(ByteAndUShort(*itMoreEncoding,sid));
			}
		}

		mEncodingPosition = mFontFileStream.GetCurrentPosition();

		if(supplements.size() > 0)
			mPrimitivesWriter.WriteCard8(0x80);
		else
			mPrimitivesWriter.WriteCard8(0);

		// assuming that 0 is in the subset glyphs IDs, which does not require encoding
		// get the encodings count
		Byte encodingGlyphsCount = std::min((Byte)(inSubsetGlyphIDs.size()-1),encodingInfo->mEncodingsCount); 

		mPrimitivesWriter.WriteCard8(encodingGlyphsCount);
		for(Byte i=0; i < encodingGlyphsCount;++i)
		{
			if(inSubsetGlyphIDs[i+1] < encodingInfo->mEncodingsCount)
				mPrimitivesWriter.WriteCard8(encodingInfo->mEncoding[inSubsetGlyphIDs[i+1]-1]);
			else
				mPrimitivesWriter.WriteCard8(0);
		}

		if(supplements.size() > 0)
		{
			mPrimitivesWriter.WriteCard8(Byte(supplements.size()));
			ByteAndUShortList::iterator itCollectedSupplements = supplements.begin();

			for(; itCollectedSupplements != supplements.end(); ++itCollectedSupplements)
			{
				mPrimitivesWriter.WriteCard8(itCollectedSupplements->first);
				mPrimitivesWriter.WriteCard16(itCollectedSupplements->second);
			}
		}
	}

	return mPrimitivesWriter.GetInternalState();
}