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; }
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)