--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicstools/bitmapfonttools/src/FNTRECRD.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,523 @@
+/*
+* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Header FNTRECRD.CPP
+*
+*/
+
+
+#include "FNTRECRD.H"
+
+const int KNumberOfPopularIndices = 128;
+const int KNumberOfBitsInByte = 8;
+const int KNumberOfBitsInTwoBytes = 16;
+
+BitmapOffset::BitmapOffset(uint16 aBitmapOffset)
+ : iBitmapOffset(aBitmapOffset)
+ {}
+
+void BitmapOffset::Externalize(ostream& out)
+ {
+ out.write((char*) &iBitmapOffset,sizeof(iBitmapOffset));
+ }
+
+CharacterMetrics::CharacterMetrics()
+ : iAscentInPixels(0),
+ iHeightInPixels(0),
+ iLeftAdjustInPixels(0),
+ iMoveInPixels(0),
+ iRightAdjustInPixels(0)
+ {
+ }
+
+
+void CharacterMetrics::Externalize(ostream& out)
+ {
+ out.write((char*) &iAscentInPixels, sizeof(iAscentInPixels));
+ out.write((char*) &iHeightInPixels, sizeof(iHeightInPixels));
+ out.write((char*) &iLeftAdjustInPixels, sizeof(iLeftAdjustInPixels));
+ out.write((char*) &iMoveInPixels, sizeof(iMoveInPixels));
+ out.write((char*) &iRightAdjustInPixels, sizeof(iRightAdjustInPixels));
+ }
+
+MetricDistributionMember::~MetricDistributionMember()
+ {
+ delete iMetric;
+ }
+
+MetricDistributionMember::MetricDistributionMember()
+ : iFrequency(0), iMetric(0)
+ {}
+
+CharacterMetrics* MetricDistributionMember::Metric() const
+ {
+ return iMetric;
+ }
+
+int MetricDistributionMember::Frequency() const
+ {
+ return iFrequency;
+ }
+
+void MetricDistributionMember::SetFrequency(int aFrequency)
+ {
+ iFrequency = aFrequency;
+ }
+
+void MetricDistributionMember::IncrementFrequency(int aIncrementBy)
+ {
+ iFrequency += aIncrementBy;
+ }
+
+void MetricDistributionMember::SetMetric(CharacterMetrics* aMetric)
+ {
+ iMetric = aMetric;
+ }
+
+void MetricDistributionMember::Externalize(ostream& out)
+ {
+ iMetric->Externalize(out);
+ }
+
+MetricDistribution::~MetricDistribution()
+ {
+ iCharacterMetricsList.Destroy();
+ }
+
+MetricDistribution* MetricDistribution::New()
+ {
+ return new MetricDistribution;
+ }
+
+MetricDistribution::MetricDistribution()
+ {}
+
+void MetricDistribution::SortMetricsByFrequency()
+ { // Only need sort the most popular 128, since after this 2 bytes will always be used
+ int maxIndex = iCharacterMetricsList.Size();
+ if (maxIndex > KNumberOfPopularIndices)
+ {
+ maxIndex = KNumberOfPopularIndices;
+ }
+ for(int indexToSet = 0; indexToSet < maxIndex; indexToSet++)
+ {
+ const CharacterMetrics& mostPopularRemaining = MostPopular(indexToSet);
+ SetIndex(mostPopularRemaining, indexToSet);
+ }
+ }
+
+void MetricDistribution::SetIndex(const CharacterMetrics& aMetrics, int aIndexToSet)
+ {
+ int currentPos = Index(aMetrics);
+ if (currentPos != aIndexToSet)
+ {
+ MetricDistributionMember* match = iCharacterMetricsList[currentPos];
+ MetricDistributionMember* swapPos = iCharacterMetricsList[aIndexToSet];
+
+ CharacterMetrics* tempMet = match->Metric();
+ const int tempFreq = match->Frequency();
+
+ match->SetMetric(swapPos->Metric());
+ match->SetFrequency(swapPos->Frequency());
+ swapPos->SetMetric(tempMet);
+ swapPos->SetFrequency(tempFreq);
+ }
+ }
+
+void MetricDistribution::AddOrIncrementMetric(const CharacterMetrics& aMetrics, int aFrequency)
+ {
+ boolean match = false;
+ const CharacterMetrics* trial = NULL;
+ MetricDistributionMember* link = NULL;
+ int index;
+ int maxIndex = iCharacterMetricsList.Size();
+
+ for(index = 0; index < maxIndex && !match; index++)
+ {
+ link = iCharacterMetricsList[index];
+ if (link)
+ trial = link->Metric();
+ if (trial && (trial->iAscentInPixels == aMetrics.iAscentInPixels)
+ && (trial->iHeightInPixels == aMetrics.iHeightInPixels)
+ && (trial->iLeftAdjustInPixels == aMetrics.iLeftAdjustInPixels)
+ && (trial->iMoveInPixels == aMetrics.iMoveInPixels)
+ && (trial->iRightAdjustInPixels == aMetrics.iRightAdjustInPixels))
+ {
+ match = true;
+ }
+ }
+ if (match)
+ {
+ link->IncrementFrequency(aFrequency);
+ }
+ else
+ {
+ MetricDistributionMember* newLink = new MetricDistributionMember;
+ newLink->IncrementFrequency(aFrequency);
+ CharacterMetrics* newMetric = new CharacterMetrics(aMetrics);
+ newLink->SetMetric(newMetric);
+ iCharacterMetricsList.Add(newLink);
+ }
+ }
+
+const CharacterMetrics& MetricDistribution::MostPopular(int aStartIndex)
+ {
+ // finds the most popular metric above index aStartIndex. Allows for a fairly quick sort of the metircs to be done.
+ MetricDistributionMember* link = NULL;
+ const CharacterMetrics* mostPopular = NULL;
+ int frequencyOfMostPopular = 0;
+ int frequency = 0;
+ int count;
+ int total = 0; // for debugging
+ const int size = iCharacterMetricsList.Size();
+ for (count = aStartIndex; count < size; count++)
+ {
+ link = iCharacterMetricsList[count];
+ frequency = link->Frequency();
+ if (frequency>frequencyOfMostPopular)
+ {
+ mostPopular = link->Metric();
+ frequencyOfMostPopular = frequency;
+ }
+ total += frequency;
+ }
+ return *mostPopular;
+ }
+
+int MetricDistribution::Index(const CharacterMetrics& aMetrics)
+ {
+ boolean same = false;
+ CharacterMetrics* match = NULL;
+ int i;
+ int size = iCharacterMetricsList.Size();
+ // see if we have this one already
+ for (i = 0; i < size; i++)
+ {
+ if (iCharacterMetricsList[i])
+ {
+ match = iCharacterMetricsList[i]->Metric();
+ }
+ if ((match->iAscentInPixels == aMetrics.iAscentInPixels)
+ && (match->iHeightInPixels == aMetrics.iHeightInPixels)
+ && (match->iLeftAdjustInPixels == aMetrics.iLeftAdjustInPixels)
+ && (match->iMoveInPixels == aMetrics.iMoveInPixels)
+ && (match->iRightAdjustInPixels == aMetrics.iRightAdjustInPixels))
+ {
+ same = true;
+ break;
+ }
+ }
+ if (!same)
+ {
+ i = -1; // not found
+ }
+ return i;
+ }
+
+void MetricDistribution::Externalize(ostream& out)
+ {
+ streamoff idOffset = iStreamId;
+ out.write(reinterpret_cast<char*>(&idOffset), sizeof(idOffset));
+ int32 numMetrics = iCharacterMetricsList.Size();
+ out.write(reinterpret_cast<char*>(&numMetrics), sizeof(numMetrics));
+ }
+
+void MetricDistribution::ExternalizeComponents(ostream& out)
+ {
+ iStreamId = out.tellp();
+ iCharacterMetricsList.Externalize(out);
+ }
+
+void Characters::Externalize(ostream& out)
+ {
+ iStreamId = out.tellp();
+ iBitmapOffsetList.Externalize(out);
+ }
+
+Characters::~Characters()
+ {
+ iBitmapOffsetList.Destroy();
+ }
+
+ByteList::ByteList()
+ : iString(), iOffset(0)
+ {
+ }
+
+void ByteList::AddBit(char aBit)
+ {
+ if (iOffset > 7)
+ NewByte();
+ const char mask = 1;
+ aBit = char(aBit & mask);
+ char byte = char(aBit << iOffset);
+ int index = iString.Length() - 1;
+ iString[index] = char(iString[index] | byte);
+ iOffset++;
+ }
+
+void ByteList::NewByte()
+ {
+ char byte = 0;
+ iString += byte;
+ iOffset = 0;
+ }
+
+int ByteList::Length() const
+ {
+ return iString.Length();
+ }
+
+void ByteList::Externalize(ostream& out)
+ {
+ int32 length = iString.Length();
+ out.write((char*) &length, sizeof(length));
+ out.write(iString.Text(), length);
+ }
+
+void CharactersBitmap::Externalize(ostream& out)
+ {
+ iStreamId = out.tellp();
+ iByteList.Externalize(out);
+ }
+
+void CharactersBitmap::AddIndex(int aIndex)
+ {// Add index to metrics into the bitmap code section
+ // Use 1 byte for most popular indices, 2 bytes otherwise
+ int power;
+ if (aIndex < KNumberOfPopularIndices)
+ {
+ iByteList.AddBit(0);
+ power = KNumberOfBitsInByte - 1;
+ }
+ else
+ {
+ iByteList.AddBit(1);
+ power = KNumberOfBitsInTwoBytes - 1;
+ }
+
+ char sigBit = 0;
+ // Add significant bits of index.
+ for(int bitToAdd = 0; bitToAdd < power; bitToAdd++)
+ {
+ sigBit = char(aIndex >> bitToAdd);
+ iByteList.AddBit(sigBit);
+ }
+ }
+
+void BitmapCodeSection::Externalize(ostream& out)
+ {
+ out.write((char*) &iStart, sizeof(iStart));
+ out.write((char*) &iEnd, sizeof(iEnd));
+ streamoff idOffset = iCharacters.iStreamId;
+ out.write(reinterpret_cast<char*>(&idOffset), sizeof(idOffset));
+ idOffset = iCharactersBitmap.iStreamId;
+ out.write(reinterpret_cast<char*>(&idOffset), sizeof(idOffset));
+ }
+
+void BitmapCodeSection::ExternalizeComponents(ostream& out)
+ {
+ iCharacters.Externalize(out);
+ iCharactersBitmap.Externalize(out);
+ }
+
+FontBitmap::FontBitmap()
+ : iPosture(PostureUpright),
+ iStrokeWeight(StrokeWeightNormal),
+ iIsProportional(efalse),
+ iCellHeightInPixels(0),
+ iAscentInPixels(0),
+ iMaxCharWidthInPixels(0),
+ iMaxNormalCharWidthInPixels(0),
+ iBitmapEncoding(0)
+ {
+ iCharacterMetrics = MetricDistribution::New();
+ }
+
+void FontBitmap::Externalize(ostream& out)
+ {
+ iStreamId = out.tellp();
+ out.write((char*) &iUid, sizeof(iUid));
+ out.put((char) iPosture);
+ out.put((char) iStrokeWeight);
+ out.put((char) iIsProportional);
+ out.write((char*) &iCellHeightInPixels, sizeof(iCellHeightInPixels));
+ out.write((char*) &iAscentInPixels, sizeof(iAscentInPixels));
+ out.write((char*) &iMaxCharWidthInPixels, sizeof(iMaxCharWidthInPixels));
+ out.write((char*) &iMaxNormalCharWidthInPixels, sizeof(iMaxNormalCharWidthInPixels));
+ out.write((char*) &iBitmapEncoding, sizeof(iBitmapEncoding));
+ iCharacterMetrics->Externalize(out);
+ iCodeSectionList.Externalize(out);
+ }
+
+void FontBitmap::ExternalizeComponents(ostream& out)
+ {
+ // write out characters and chactersbitmap records
+ iCharacterMetrics->ExternalizeComponents(out);
+ int size = iCodeSectionList.Size();
+ for (int i = 0; i < size; i++)
+ {
+ iCodeSectionList[i]->ExternalizeComponents(out);
+ }
+ }
+
+FontBitmap::~FontBitmap()
+ {
+ iCodeSectionList.Destroy();
+ delete iCharacterMetrics;
+ }
+
+TypefaceFontBitmap::TypefaceFontBitmap(FontBitmap* aFontBitmap)
+ : iFontBitmap(aFontBitmap),
+ iFontBitmapUid(KNullUid),
+ iWidthFactor(1),
+ iHeightFactor(1)
+ {
+ }
+
+TypefaceFontBitmap::TypefaceFontBitmap(uid aFontBitmapUid)
+ : iFontBitmap(NULL),
+ iFontBitmapUid(aFontBitmapUid),
+ iWidthFactor(1),
+ iHeightFactor(1)
+ {
+ }
+
+void TypefaceFontBitmap::Externalize(ostream& out)
+ {
+ if (iFontBitmap)
+ out.write((char*) &iFontBitmap->iUid, sizeof(iFontBitmap->iUid));
+ else
+ out.write((char*) &iFontBitmapUid, sizeof(iFontBitmapUid));
+ out.write((char*) &iWidthFactor, sizeof(iWidthFactor));
+ out.write((char*) &iHeightFactor, sizeof(iHeightFactor));
+ }
+
+void FntTypeface::Externalize(ostream& out)
+ {
+ iStreamId = out.tellp();
+ Typeface::Externalize(out);
+ iTypefaceFontBitmapList.Externalize(out);
+ }
+
+FontStoreFile::FontStoreFile()
+ : iCollectionUid(KNullUid),
+ iKPixelAspectRatio(1000),
+ iCopyrightInfo(),
+ iDataStreamId(0)
+ {
+ }
+
+void FontStoreFile::AddTypeface(FntTypeface *aTypeface)
+ {
+ iTypefaceList.Add(aTypeface);
+ for (int i = 0; i < aTypeface->iTypefaceFontBitmapList.Size(); i++)
+ {
+ if (aTypeface->iTypefaceFontBitmapList[i]->iFontBitmap)
+ iFontBitmapList.Add(aTypeface->iTypefaceFontBitmapList[i]->iFontBitmap);
+ }
+ }
+
+void FontStoreFile::AddFontBitmap(FontBitmap* aFontBitmap)
+ {
+ iFontBitmapList.Add(aFontBitmap);
+ }
+
+void FontStoreFile::Externalize(ostream& out)
+ {
+ ExternalizeHeader(out);
+ ExternalizeComponents(out);
+ }
+
+void FontStoreFile::ExternalizeHeader(ostream& out)
+ {
+ out.write((char*) &KStoreWriteOnceLayoutUid, sizeof(KStoreWriteOnceLayoutUid));
+ out.write((char*) &KFontStoreFileUid, sizeof(KFontStoreFileUid));
+ out.write((char*) &KNullUid, sizeof(KNullUid));
+ out.write((char*) &KFontStoreFileChecksum, sizeof(KFontStoreFileChecksum));
+ streamoff idOffset = iStreamId;
+ out.write(reinterpret_cast<char*>(&idOffset), sizeof(idOffset));
+ iStreamId = out.tellp();
+ out.write((char*) &KFnttranVersion, sizeof(KFnttranVersion));
+ out.write((char*) &iCollectionUid, sizeof(iCollectionUid));
+ out.write((char*) &iKPixelAspectRatio, sizeof(iKPixelAspectRatio));
+ idOffset = iDataStreamId;
+ out.write(reinterpret_cast<char*>(&idOffset), sizeof(idOffset));
+ iCopyrightInfo.Externalize(out);
+ }
+
+void FontStoreFile::ExternalizeComponents(ostream& out)
+ {
+ iDataStreamId = out.tellp();
+ iFontBitmapList.Externalize(out);
+ iTypefaceList.Externalize(out);
+ iFontBitmapList.ExternalizeComponents(out);
+ }
+
+boolean FontStore::Store(const String& aFilename)
+ {
+ boolean state = efalse;
+ ofstream fout;
+ String string = aFilename;
+ fout.open(string.Text(), ios::binary);
+ if (!fout.fail())
+ {
+ iFontStoreFile->Externalize(fout);
+ fout.close();
+ fout.open(string.Text(), ios::binary | ios::trunc);
+ iFontStoreFile->Externalize(fout);
+ fout.close();
+ state = etrue;
+ }
+ return state;
+ }
+
+void FontStore::AddFontStoreFile(FontStoreFile* aFontStoreFile)
+ {
+ iFontStoreFile = aFontStoreFile;
+ }
+
+void FontStore::AddFontBitmap(FontBitmap *aFontBitmap)
+ {
+ iFontBitmapList.Add(aFontBitmap);
+ }
+
+Record* FontStore::FindFontBitmap(String& aLabel)
+ {
+ return iFontBitmapList.LabelToRecord(aLabel);
+ }
+
+void FontStore::AddTypeface(FntTypeface *aTypeface)
+ {
+ iTypefaceList.Add(aTypeface);
+ }
+
+Record* FontStore::FindTypeface(String& aLabel)
+ {
+ return iTypefaceList.LabelToRecord(aLabel);
+ }
+
+FontStore::FontStore()
+ : iFontStoreFile(NULL),
+ iFontBitmapList(),
+ iTypefaceList()
+ {
+ }
+
+FontStore::~FontStore()
+ {
+ delete iFontStoreFile;
+ iFontBitmapList.Destroy();
+ iTypefaceList.Destroy();
+ }