Пример #1
0
bool WrittenFontTrueType::AddToANSIRepresentation(	const GlyphUnicodeMappingList& inGlyphsList,
													UShortList& outEncodedCharacters)
{
	// i'm totally relying on the text here, which is fine till i'll do ligatures, in which case
	// i'll need to make something different out of the text.
	// as you can see this has little to do with glyphs (mainly cause i can't use FreeType to map the glyphs
	// back to the rleevant unicode values...but no need anyways...that's why i carry the text).
	UShortList candidates;
	BoolAndByte encodingResult(true,0);
	WinAnsiEncoding winAnsiEncoding;
	GlyphUnicodeMappingList::const_iterator it = inGlyphsList.begin(); 

	for(; it != inGlyphsList.end() && encodingResult.first; ++it)
	{
		// don't bother with characters of more (or less) than one unicode
		if(it->mUnicodeValues.size() != 1)
		{
			encodingResult.first = false;
		}
		else if(0x2022 == it->mUnicodeValues.front())
		{
			// From the reference:
			// In WinAnsiEncoding, all unused codes greater than 40 map to the bullet character. 
			// However, only code 225 is specifically assigned to the bullet character; other codes are subject to future reassignment.

			// now i don't know if it's related or not...but acrobat isn't happy when i'm using winansi with bullet. and text coming after that bullet may be
			// corrupted.
			// so i'm forcing CID if i hit bullet till i know better.
			encodingResult.first = false;
		}
		else
		{
			encodingResult = winAnsiEncoding.Encode(it->mUnicodeValues.front());
			if(encodingResult.first)
				candidates.push_back(encodingResult.second);
		}
	}

	if(encodingResult.first)
	{
		// for the first time, add also 0,0 mapping
		if(mANSIRepresentation->mGlyphIDToEncodedChar.size() == 0)
			mANSIRepresentation->mGlyphIDToEncodedChar.insert(UIntToGlyphEncodingInfoMap::value_type(0,GlyphEncodingInfo(0,0)));


		GlyphUnicodeMappingList::const_iterator itGlyphs = inGlyphsList.begin();
		UShortList::iterator itEncoded = candidates.begin();
		for(; itGlyphs != inGlyphsList.end(); ++ itGlyphs,++itEncoded)
		{
			if(mANSIRepresentation->mGlyphIDToEncodedChar.find(itGlyphs->mGlyphCode) == mANSIRepresentation->mGlyphIDToEncodedChar.end())
				mANSIRepresentation->mGlyphIDToEncodedChar.insert(
					UIntToGlyphEncodingInfoMap::value_type(itGlyphs->mGlyphCode,GlyphEncodingInfo(*itEncoded,itGlyphs->mUnicodeValues)));
		}

		outEncodedCharacters = candidates;
	}

	return encodingResult.first;
}
Пример #2
0
bool WrittenFontTrueType::AddToANSIRepresentation(	const GlyphUnicodeMappingList& inGlyphsList,
													UShortList& outEncodedCharacters)
{
	// i'm totally relying on the text here, which is fine till i'll do ligatures, in which case
	// i'll need to make something different out of the text.
	// as you can see this has little to do with glyphs (mainly cause i can't use FreeType to map the glyphs
	// back to the rleevant unicode values...but no need anyways...that's why i carry the text).
	UShortList candidates;
	BoolAndByte encodingResult(true,0);
	WinAnsiEncoding winAnsiEncoding;
	GlyphUnicodeMappingList::const_iterator it = inGlyphsList.begin(); 

	for(; it != inGlyphsList.end() && encodingResult.first; ++it)
	{
		// don't bother with characters of more (or less) than one unicode
		if(it->mUnicodeValues.size() != 1)
		{
			encodingResult.first = false;
		}
		else
		{
			encodingResult = winAnsiEncoding.Encode(it->mUnicodeValues.front());
			if(encodingResult.first)
				candidates.push_back(encodingResult.second);
		}
	}

	if(encodingResult.first)
	{
		// for the first time, add also 0,0 mapping
		if(mANSIRepresentation->mGlyphIDToEncodedChar.size() == 0)
			mANSIRepresentation->mGlyphIDToEncodedChar.insert(UIntToGlyphEncodingInfoMap::value_type(0,GlyphEncodingInfo(0,0)));


		GlyphUnicodeMappingList::const_iterator itGlyphs = inGlyphsList.begin();
		UShortList::iterator itEncoded = candidates.begin();
		for(; itGlyphs != inGlyphsList.end(); ++ itGlyphs,++itEncoded)
		{
			if(mANSIRepresentation->mGlyphIDToEncodedChar.find(itGlyphs->mGlyphCode) == mANSIRepresentation->mGlyphIDToEncodedChar.end())
				mANSIRepresentation->mGlyphIDToEncodedChar.insert(
					UIntToGlyphEncodingInfoMap::value_type(itGlyphs->mGlyphCode,GlyphEncodingInfo(*itEncoded,itGlyphs->mUnicodeValues)));
		}

		outEncodedCharacters = candidates;
	}

	return encodingResult.first;
}
EStatusCode AbstractContentContext::WriteTextCommandWithDirectGlyphSelection(const GlyphUnicodeMappingList& inText,ITextCommand* inTextCommand)
{
	PDFUsedFont* currentFont = mGraphicStack.GetCurrentState().mFont;
	if(!currentFont)
	{
		TRACE_LOG("AbstractContentContext::WriteTextCommandWithDirectGlyphSelection, Cannot write text, no current font is defined");
		return PDFHummus::eFailure;
	}

	ObjectIDType fontObjectID;
	UShortList encodedCharactersList;
	bool writeAsCID;	

	if(currentFont->EncodeStringForShowing(inText,fontObjectID,encodedCharactersList,writeAsCID) != PDFHummus::eSuccess)
	{
		TRACE_LOG("AbstractcontextContext::WriteTextCommandWithDirectGlyphSelection, Unexepcted failure, Cannot encode characters");
		return PDFHummus::eFailure;
	}
	

	// Write the font reference (only if required)
	std::string fontName = GetResourcesDictionary()->AddFontMapping(fontObjectID);

	if(mGraphicStack.GetCurrentState().mPlacedFontName != fontName ||
		mGraphicStack.GetCurrentState().mPlacedFontSize != mGraphicStack.GetCurrentState().mFontSize)
		TfLow(fontName,mGraphicStack.GetCurrentState().mFontSize);
	
	// Now write the string using the text command
	OutputStringBufferStream stringStream;
	char formattingBuffer[5];
	UShortList::iterator it = encodedCharactersList.begin();
	if(writeAsCID)
	{
		for(;it!= encodedCharactersList.end();++it)
		{
			SAFE_SPRINTF_2(formattingBuffer,5,"%02x%02x",((*it)>>8) & 0x00ff,(*it) & 0x00ff);
			stringStream.Write((const Byte*)formattingBuffer,4);
		}
		inTextCommand->WriteHexStringCommand(stringStream.ToString());
	}
	else
	{
		for(;it!= encodedCharactersList.end();++it)