コード例 #1
0
EStatusCode TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset(	FreeTypeFaceWrapper& inFontInfo, /*consider requiring only the file path...actually i don't need the whole thing*/
																const UIntVector& inSubsetGlyphIDs,
																bool& outNotEmbedded,
																MyStringBuf& outFontProgram)
{
	EStatusCode status;
	unsigned long* locaTable = NULL;

	do
	{
		UIntVector subsetGlyphIDs = inSubsetGlyphIDs;

		status = mTrueTypeFile.OpenFile(inFontInfo.GetFontFilePath());
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG1("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, cannot open true type font file at %s",inFontInfo.GetFontFilePath().c_str());
			break;
		}

		status = mTrueTypeInput.ReadOpenTypeFile(mTrueTypeFile.GetInputStream(),(unsigned short)inFontInfo.GetFontIndex());
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to read true type file");
			break;
		}

		if(mTrueTypeInput.GetOpenTypeFontType() != EOpenTypeTrueType)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, font file is not true type, so there is an exceptions here. expecting true types only");
			break;
		}
	
		// see if font may be embedded
		if(mTrueTypeInput.mOS2Exists && !FSType(mTrueTypeInput.mOS2.fsType).CanEmbed())
		{
			outNotEmbedded = true;
			return PDFHummus::eSuccess;
		}
		else
			outNotEmbedded = false;

		AddDependentGlyphs(subsetGlyphIDs);

		// K. this needs a bit explaining.
		// i want to leave the glyph IDs as they were in the original font.
		// this allows me to write a more comfotable font definition. something which is generic enough
		// this assumption requires that the font will contain the glyphs in their original position
		// to allow that, when the glyph count is smaller than the actual glyphs count, i'm
		// padding with 0 length glyphs (their loca entries just don't move).
		// don't worry - it's perfectly kosher.
		// so - bottom line - the glyphs count will actually be 1 more than the maxium glyph index.
		// and from here i'll just place the glyphs in their original indexes, and fill in the 
		// vacant glyphs with empties.
		mSubsetFontGlyphsCount = subsetGlyphIDs.back() + 1;
		
		mFontFileStream.Assign(&outFontProgram);
		mPrimitivesWriter.SetOpenTypeStream(&mFontFileStream);

		// assign also to some reader streams, so i can read items for checksums calculations
		mFontFileReaderStream.Assign(&outFontProgram);
		mPrimitivesReader.SetOpenTypeStream(&mFontFileReaderStream);


		status = WriteTrueTypeHeader();
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write true type header");
			break;
		}

		status = WriteHead();
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write head table");
			break;
		}

		status = WriteHHea();
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write hhea table");
			break;
		}

		status = WriteHMtx();
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write hmtx table");
			break;
		}

		status = WriteMaxp();
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write Maxp table");
			break;
		}

		if(mTrueTypeInput.mCVTExists)
		{
			status = WriteCVT();
			if(status != PDFHummus::eSuccess)
			{
				TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write cvt table");
				break;
			}
		}

		if(mTrueTypeInput.mFPGMExists)
		{
			status = WriteFPGM();
			if(status != PDFHummus::eSuccess)
			{
				TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write fpgm table");
				break;
			}
		}

		if(mTrueTypeInput.mPREPExists)
		{
			status = WritePREP();
			if(status != PDFHummus::eSuccess)
			{
				TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write prep table");
				break;	
			}
		}

		status = WriteNAME();
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write name table");
			break;	
		}

        if(mTrueTypeInput.mOS2Exists)
        {
            status = WriteOS2();
            if(status != PDFHummus::eSuccess)
            {
                TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write os2 table");
                break;
            }
        }

		status = WriteCMAP();
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write cmap table");
			break;	
		}

		locaTable = new unsigned long[mSubsetFontGlyphsCount+1];

		status = WriteGlyf(subsetGlyphIDs,locaTable);
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write prep table");
			break;
		}

		status = WriteLoca(locaTable);
		if(status != PDFHummus::eSuccess)
		{
			TRACE_LOG("TrueTypeEmbeddedFontWriter::CreateTrueTypeSubset, failed to write loca table");
			break;
		}

		status = CreateHeadTableCheckSumAdjustment();
	}while(false);

	delete[] locaTable;
	mTrueTypeFile.CloseFile();
	return status;
}