fontservices/freetypefontrasteriser/src/FTRAST2.CPP
branchRCL_3
changeset 11 6971d1c87c9a
parent 0 1fb32624e06b
child 54 748ec5531811
equal deleted inserted replaced
5:e96e8a131979 11:6971d1c87c9a
   157 		RHeap* aHeap, COpenFontSessionCacheList* aSessionCacheList,
   157 		RHeap* aHeap, COpenFontSessionCacheList* aSessionCacheList,
   158 		const TOpenFontSpec& aDesiredFontSpec, TInt aPixelWidth, TInt aPixelHeight,
   158 		const TOpenFontSpec& aDesiredFontSpec, TInt aPixelWidth, TInt aPixelHeight,
   159 		COpenFont*& aFont, TOpenFontSpec& aActualFontSpec, TInt aMaxHeight);
   159 		COpenFont*& aFont, TOpenFontSpec& aActualFontSpec, TInt aMaxHeight);
   160 	TBool HasUnicodeCharacterL(TInt aFaceIndex, TInt aCode) const;
   160 	TBool HasUnicodeCharacterL(TInt aFaceIndex, TInt aCode) const;
   161 	TAny* GetTrueTypeTable(TInt& aError, TInt aFaceIndex, TUint32 aTag, TInt* aLength);
   161 	TAny* GetTrueTypeTable(TInt& aError, TInt aFaceIndex, TUint32 aTag, TInt* aLength);
   162 	TInt GetGlyphOutline(TInt aFaceIndex, TUint aCode, 
       
   163 	        TBool aIsGlyphId, TBool, TAny*& aOutline, TInt &aLength);
       
   164 
   162 
   165 private:
   163 private:
   166 	static void SetGlyphMetrics(FT_GlyphSlot aGlyphSlot, TOpenFontGlyphData* aGlyphData);
   164 	static void SetGlyphMetrics(FT_GlyphSlot aGlyphSlot, TOpenFontGlyphData* aGlyphData);
   167 	void GetNearestFontInPixelsL(
   165 	void GetNearestFontInPixelsL(
   168 		RHeap* aHeap, COpenFontSessionCacheList* aSessionCacheList,
   166 		RHeap* aHeap, COpenFontSessionCacheList* aSessionCacheList,
   182 	TText8* iFileName; // in null-terminated UTF8 so that it can be passed to fopen
   180 	TText8* iFileName; // in null-terminated UTF8 so that it can be passed to fopen
   183 	RHashMap<TUint32, TPtrC8> iTableStore;
   181 	RHashMap<TUint32, TPtrC8> iTableStore;
   184 	};
   182 	};
   185 
   183 
   186 NONSHARABLE_CLASS(CFreeTypeFont) : public COpenFont, public MOpenFontShapingExtension, 
   184 NONSHARABLE_CLASS(CFreeTypeFont) : public COpenFont, public MOpenFontShapingExtension, 
   187     public MOpenFontTrueTypeExtension, public MOpenFontGlyphOutlineExtension
   185     public MOpenFontTrueTypeExtension
   188 	{
   186 	{
   189 public:
   187 public:
   190 	static CFreeTypeFont* NewL(
   188 	static CFreeTypeFont* NewL(
   191 		RHeap* aHeap, COpenFontSessionCacheList* aSessionCacheList, CFreeTypeFontFile* aFontFile,
   189 		RHeap* aHeap, COpenFontSessionCacheList* aSessionCacheList, CFreeTypeFontFile* aFontFile,
   192 		TInt aFaceIndex, TInt aSizeInPixels, TInt32 aWidthFactor, TInt32 aSlantFactor,
   190 		TInt aFaceIndex, TInt aSizeInPixels, TInt32 aWidthFactor, TInt32 aSlantFactor,
   216 
   214 
   217 	// virtual functions from MOpenFontTrueTypeExtension
   215 	// virtual functions from MOpenFontTrueTypeExtension
   218 	TAny* GetTrueTypeTable(TInt& aError, TUint32 aTag, TInt* aLength);
   216 	TAny* GetTrueTypeTable(TInt& aError, TUint32 aTag, TInt* aLength);
   219 	TInt  ReleaseTrueTypeTable(TAny* aTable);
   217 	TInt  ReleaseTrueTypeTable(TAny* aTable);
   220 	TBool HasTrueTypeTable(TUint32 aTag);
   218 	TBool HasTrueTypeTable(TUint32 aTag);
   221 	TInt GetGlyphOutline(TUint aCode, TBool aIsGlyphId, 
       
   222 	            TBool aHinted, TAny*& aOutline, TInt &aLength);
       
   223 
   219 
   224 	inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW;
   220 	inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW;
   225 	inline TAny* operator new(TUint aSize) __NO_THROW;
   221 	inline TAny* operator new(TUint aSize) __NO_THROW;
   226 	inline void operator delete(void*, TAny*) __NO_THROW;
   222 	inline void operator delete(void*, TAny*) __NO_THROW;
   227 	inline void operator delete(void*) __NO_THROW;
   223 	inline void operator delete(void*) __NO_THROW;
  1068 	{
  1064 	{
  1069 	if (aUid == KUidOpenFontShapingExtension)
  1065 	if (aUid == KUidOpenFontShapingExtension)
  1070 		aParam = static_cast<MOpenFontShapingExtension*>(this);
  1066 		aParam = static_cast<MOpenFontShapingExtension*>(this);
  1071 	else if (aUid == KUidOpenFontTrueTypeExtension)	
  1067 	else if (aUid == KUidOpenFontTrueTypeExtension)	
  1072 		aParam = static_cast<MOpenFontTrueTypeExtension*>(this);
  1068 		aParam = static_cast<MOpenFontTrueTypeExtension*>(this);
  1073 	else if (aUid == KUidOpenFontGlyphOutlineExtension)
       
  1074 	    aParam = static_cast<MOpenFontGlyphOutlineExtension*>(this);
       
  1075 	else
  1069 	else
  1076 		COpenFont::ExtendedInterface(aUid, aParam);
  1070 		COpenFont::ExtendedInterface(aUid, aParam);
  1077 	}
  1071 	}
  1078  
  1072  
  1079 // Rasterize a glyph from unicode value of aCode.
  1073 // Rasterize a glyph from unicode value of aCode.
  1173 		aOut.iYScaleFactor = 1.0;
  1167 		aOut.iYScaleFactor = 1.0;
  1174 		}
  1168 		}
  1175 	}
  1169 	}
  1176 
  1170 
  1177 
  1171 
  1178 TInt CFreeTypeFont::GetGlyphOutline(TUint aCode, TBool aIsGlyphId, 
  1172 
  1179                 TBool aHinted, TAny*& aOutline, TInt& aLength)
       
  1180     {
       
  1181     CFreeTypeFontFile* file = (CFreeTypeFontFile*)File();
       
  1182     if (!file)
       
  1183         {
       
  1184         return KErrNotFound;
       
  1185         }
       
  1186     aHinted = EFalse; // to avoid 'unused' warning.
       
  1187     
       
  1188     return file->GetGlyphOutline(FaceIndex(), aCode, aIsGlyphId, aHinted, aOutline, aLength);
       
  1189     }
       
  1190 
  1173 
  1191 TAny* CFreeTypeFont::GetTrueTypeTable(TInt& aError, TUint32 aTag, TInt* aLength)
  1174 TAny* CFreeTypeFont::GetTrueTypeTable(TInt& aError, TUint32 aTag, TInt* aLength)
  1192 	{
  1175 	{
  1193 	CFreeTypeFontFile* file = (CFreeTypeFontFile*)File();
  1176 	CFreeTypeFontFile* file = (CFreeTypeFontFile*)File();
  1194 	if (!file)
  1177 	if (!file)
  1299 		iContext->TranslateMonochromeGlyphBitmap(aFace->Face()->glyph,aGlyphData);
  1282 		iContext->TranslateMonochromeGlyphBitmap(aFace->Face()->glyph,aGlyphData);
  1300 	else
  1283 	else
  1301 		iContext->TranslateAntiAliasedGlyphBitmap(aFace->Face()->glyph,aGlyphData);
  1284 		iContext->TranslateAntiAliasedGlyphBitmap(aFace->Face()->glyph,aGlyphData);
  1302 	}
  1285 	}
  1303 
  1286 
  1304 enum vg_commands {
       
  1305     VG_CMD_NONE = 0,
       
  1306     VG_CMD_MOVETO,
       
  1307     VG_CMD_LINETO,
       
  1308     VG_CMD_CONICTO,
       
  1309     VG_CMD_CUBICTO,
       
  1310     VG_CMD_CLOSE
       
  1311 };
       
  1312 
       
  1313 
       
  1314 enum contour_states 
       
  1315     {
       
  1316     CONTOUR_STATE_NOT_STARTED = 0,
       
  1317     CONTOUR_STATE_START,
       
  1318     CONTOUR_STATE_CONIC,
       
  1319     CONTOUR_STATE_CUBIC1,
       
  1320     CONTOUR_STATE_CUBIC2,
       
  1321     CONTOUR_STATE_MAX
       
  1322     };
       
  1323 
       
  1324 static const TInt StateTransitions[CONTOUR_STATE_MAX][3] = 
       
  1325     {
       
  1326         {CONTOUR_STATE_START, -1, -1},
       
  1327         {CONTOUR_STATE_START, CONTOUR_STATE_CONIC, CONTOUR_STATE_CUBIC1},
       
  1328         {CONTOUR_STATE_START, -1, -1},
       
  1329         {-1, -1, CONTOUR_STATE_CUBIC2}, 
       
  1330         {CONTOUR_STATE_START, -1, -1}, 
       
  1331     };
       
  1332 
       
  1333 static const TInt OutputCommands[CONTOUR_STATE_MAX][3] = 
       
  1334     {
       
  1335         {VG_CMD_MOVETO, -1, -1},
       
  1336         {VG_CMD_LINETO, VG_CMD_NONE, VG_CMD_NONE},
       
  1337         {VG_CMD_CONICTO, -1, -1},
       
  1338         {-1, -1, VG_CMD_NONE}, 
       
  1339         {VG_CMD_CUBICTO, -1, -1},
       
  1340     };
       
  1341 
       
  1342 
       
  1343 class MVGCommandProcessor 
       
  1344     {
       
  1345 public:
       
  1346     virtual TInt ProcessCommand(TInt8 cmd, FT_Vector &start, FT_Vector &end) = 0;
       
  1347     };
       
  1348 
       
  1349 class COutlineStringBuilder: public MVGCommandProcessor, public CBase 
       
  1350     {
       
  1351 private:
       
  1352     TUint8 *iBuffer;
       
  1353     TUint8 *iCur;
       
  1354     TInt iLen;
       
  1355 
       
  1356 
       
  1357 public:
       
  1358     COutlineStringBuilder():iBuffer(0), iLen(2000) 
       
  1359         { 
       
  1360         iBuffer = (TUint8 *)User::Alloc(iLen);
       
  1361         iCur = iBuffer;
       
  1362         }
       
  1363     
       
  1364     ~COutlineStringBuilder() 
       
  1365         {
       
  1366         // ownership of the buffer is transferred to the caller.
       
  1367         }
       
  1368     
       
  1369     
       
  1370     TUint8 *GetBuffer(TInt &aLen) 
       
  1371         {
       
  1372         aLen = iCur - iBuffer;
       
  1373         *iCur = '\0';
       
  1374         return iBuffer;
       
  1375         }
       
  1376     
       
  1377     TInt AppendChar(char ch)
       
  1378         {
       
  1379         *(iCur++) = ch;
       
  1380         return 0;
       
  1381         }
       
  1382     
       
  1383     TInt AppendFTPos(FT_Pos n)
       
  1384         {
       
  1385         int divisor = 1;
       
  1386         FT_Pos tmp = (n > 0) ? n : (-n);
       
  1387         while (tmp/divisor >= 10) {
       
  1388             divisor *= 10;
       
  1389         }
       
  1390         
       
  1391         if (n < 0)
       
  1392             {
       
  1393             AppendChar('-');
       
  1394             }
       
  1395         
       
  1396         for ( ; divisor >= 1; divisor /= 10)
       
  1397             {
       
  1398             AppendChar('0' + tmp/divisor);
       
  1399             tmp = tmp % divisor;
       
  1400             }
       
  1401         
       
  1402         return 0;
       
  1403         }
       
  1404     
       
  1405     TInt AppendCoord(FT_Pos x, FT_Pos y) 
       
  1406         {
       
  1407         AppendFTPos(x);
       
  1408         AppendChar(',');
       
  1409         AppendFTPos(y);
       
  1410         AppendChar(' ');
       
  1411         return 0;
       
  1412         }
       
  1413     
       
  1414     TInt
       
  1415     ProcessCommand(TInt8 cmd, FT_Vector &start, FT_Vector &end) 
       
  1416         {
       
  1417         FT_Vector *st = &start;
       
  1418 
       
  1419         if (iCur + 64 > iBuffer + iLen) 
       
  1420             {
       
  1421             TUint distance = iCur - iBuffer;
       
  1422             iLen += 1000;
       
  1423             TUint8 *newBuffer = (TUint8 *)User::ReAlloc(iBuffer, iLen);
       
  1424             iBuffer = newBuffer;
       
  1425             iCur = iBuffer + distance;
       
  1426             }
       
  1427         
       
  1428         if (VG_CMD_MOVETO == cmd) 
       
  1429             {
       
  1430             AppendChar('M');
       
  1431             AppendCoord(start.x, start.y);
       
  1432             }
       
  1433         else if (VG_CMD_LINETO == cmd)
       
  1434             {
       
  1435             AppendChar('L');
       
  1436             AppendCoord(end.x, end.y);
       
  1437             }
       
  1438         else if (VG_CMD_CONICTO == cmd)
       
  1439             {
       
  1440             AppendChar('Q');
       
  1441             AppendCoord((st+1)->x, (st+1)->y);
       
  1442             AppendCoord(end.x, end.y);
       
  1443             }
       
  1444         else if (VG_CMD_CUBICTO == cmd)
       
  1445             {
       
  1446             AppendChar('Q');
       
  1447             AppendCoord((st+1)->x, (st+1)->y);
       
  1448             AppendCoord((st+2)->x, (st+2)->y);
       
  1449             AppendCoord(end.x, end.y);
       
  1450             }
       
  1451         else if (VG_CMD_CLOSE == cmd)
       
  1452             {
       
  1453             AppendChar('Z');
       
  1454             AppendChar(' ');
       
  1455             }
       
  1456         
       
  1457         return KErrNone;
       
  1458         }
       
  1459     };
       
  1460 
       
  1461 
       
  1462 class COutlineConvDirector: public CBase {
       
  1463 private:
       
  1464     MVGCommandProcessor *iProcessor;
       
  1465     const FT_Outline *iOutline; 
       
  1466     FT_Outline iNewOutline;
       
  1467 
       
  1468     
       
  1469 private:
       
  1470     char
       
  1471     GetNextPointType(char aTag) 
       
  1472         {
       
  1473         char ret = FT_CURVE_TAG(aTag);
       
  1474         if (FT_CURVE_TAG_ON == ret)
       
  1475             {
       
  1476             ret = 0;
       
  1477             }
       
  1478         else if (FT_CURVE_TAG_CONIC == ret)
       
  1479             {
       
  1480             ret = 1;
       
  1481             }
       
  1482         else if (FT_CURVE_TAG_CUBIC == ret)
       
  1483             {
       
  1484             ret = 2;
       
  1485             }
       
  1486         else 
       
  1487             {
       
  1488             __ASSERT_DEBUG(0, User::Panic(_L("IncorrectState"), -1));
       
  1489             }
       
  1490         return ret;
       
  1491         }
       
  1492     
       
  1493     TInt SwapPoints(const TInt i1, const TInt i2)
       
  1494         {
       
  1495         FT_Vector tmpVector = iOutline->points[i1];
       
  1496         char tmpTags = iOutline->tags[i1];
       
  1497         iOutline->points[i1] = iOutline->points[i2];
       
  1498         iOutline->tags[i1] = iOutline->tags[i2];
       
  1499         iOutline->points[i2] = tmpVector;
       
  1500         iOutline->tags[i2] = tmpTags;
       
  1501         return 0;
       
  1502         }
       
  1503     
       
  1504     TInt MoveFirstOnPointToBeginning(const TInt aStartIndex, const TInt aEndIndex) 
       
  1505         {
       
  1506         /* Contours of three or more points are valid, and single points 
       
  1507          * (reference points, technically not contours) are also valid as 
       
  1508          * special cases in TrueType. 
       
  1509          */ 
       
  1510         char curTag = FT_CURVE_TAG(iOutline->tags[aStartIndex]);
       
  1511         
       
  1512         // so a contour having only one point which is 'off' is invalid!
       
  1513         __ASSERT_DEBUG(!(aEndIndex - aStartIndex == 0 && FT_CURVE_TAG_ON != curTag), 
       
  1514                 User::Panic(_L("Contour consisting of 1 'off' point."), -1));
       
  1515         
       
  1516         /* Contours consisting of two points are not a valid configuration. */
       
  1517         __ASSERT_DEBUG(aEndIndex - aStartIndex != 1, 
       
  1518                 User::Panic(_L("Contour consisting of two points."), -1));
       
  1519         
       
  1520         if (FT_CURVE_TAG_ON == curTag) 
       
  1521             {
       
  1522             return KErrNone;
       
  1523             }
       
  1524         TInt firstOnIndex = -1;
       
  1525         TInt i = 0;
       
  1526         for (i = 1+aStartIndex; i < aEndIndex; ++i)
       
  1527             {
       
  1528             if (FT_CURVE_TAG_ON == FT_CURVE_TAG(iOutline->tags[i]))
       
  1529                 {
       
  1530                 firstOnIndex = i;
       
  1531                 break;
       
  1532                 }
       
  1533             }
       
  1534         __ASSERT_DEBUG(-1 != firstOnIndex, 
       
  1535                 User::Panic(_L("Contour containing no 'on' point."), -1));
       
  1536         
       
  1537         for (i = firstOnIndex-1; i >= aStartIndex; --i)
       
  1538             {
       
  1539             for (TInt j = i; j < aEndIndex; ++j)
       
  1540                 {
       
  1541                 SwapPoints(j, j+1);
       
  1542                 }
       
  1543             }
       
  1544         
       
  1545         return KErrNone;
       
  1546         }
       
  1547     
       
  1548     TInt
       
  1549     ConvertContour(const TInt aStartIndex, const TInt aEndIndex)
       
  1550         {
       
  1551         /* Contours consisting of two 
       
  1552          * points are not a valid configuration. 
       
  1553          */
       
  1554         __ASSERT_DEBUG(aEndIndex - aStartIndex != 1, 
       
  1555                 User::Panic(_L("Contour consisting of two points."), -1));
       
  1556         
       
  1557         TInt state = CONTOUR_STATE_NOT_STARTED, newState = -1;
       
  1558         TInt cmdStart = aStartIndex, cmdCur = 0, command = -1;
       
  1559         
       
  1560         char ptype = GetNextPointType(iNewOutline.tags[cmdStart]);
       
  1561         __ASSERT_DEBUG(0 == ptype, User::Panic(_L("IncorrectState"), -1)); 
       
  1562         state = CONTOUR_STATE_START;
       
  1563         iProcessor->ProcessCommand(VG_CMD_MOVETO, 
       
  1564                 iNewOutline.points[aStartIndex], iNewOutline.points[aStartIndex]);
       
  1565         
       
  1566         
       
  1567         for (cmdCur = cmdStart + 1; cmdCur <= aEndIndex; ++cmdCur)
       
  1568             {
       
  1569             ptype = GetNextPointType(iNewOutline.tags[cmdCur]);
       
  1570             newState = StateTransitions[state][ptype];
       
  1571             __ASSERT_DEBUG(-1 != newState, User::Panic(_L("IncorrectState"), -1));
       
  1572             command = OutputCommands[state][ptype];
       
  1573             __ASSERT_DEBUG(-1 != command, User::Panic(_L("IncorrectState"), -1));
       
  1574             
       
  1575             if (VG_CMD_NONE != command)
       
  1576                 {
       
  1577                 iProcessor->ProcessCommand(command, 
       
  1578                         iNewOutline.points[cmdStart], iNewOutline.points[cmdCur]);
       
  1579                 cmdStart = cmdCur;
       
  1580                 }
       
  1581             state = newState;
       
  1582             }
       
  1583         
       
  1584         if (CONTOUR_STATE_CONIC == state)
       
  1585             {
       
  1586             iProcessor->ProcessCommand(VG_CMD_CONICTO, iNewOutline.points[cmdStart], 
       
  1587                     iNewOutline.points[aStartIndex]);
       
  1588             }
       
  1589         else if (CONTOUR_STATE_CUBIC2 == state)
       
  1590             {
       
  1591             iProcessor->ProcessCommand(VG_CMD_CUBICTO, iNewOutline.points[cmdStart], 
       
  1592                     iNewOutline.points[aStartIndex]);
       
  1593             }
       
  1594         iProcessor->ProcessCommand(VG_CMD_CLOSE, 
       
  1595                 iNewOutline.points[aStartIndex], iNewOutline.points[aStartIndex]);
       
  1596         
       
  1597         return KErrNone;
       
  1598         }
       
  1599 
       
  1600 
       
  1601     TInt Preprocess() 
       
  1602         {
       
  1603         /* two successive conic "off" points forces the rasterizer to 
       
  1604          * create (during the scan-line conversion process exclusively) a 
       
  1605          * virtual "on" point amidst them, at their exact middle.
       
  1606          */
       
  1607         char prevTag = FT_CURVE_TAG(iOutline->tags[0]), currentTag = 0;
       
  1608         TInt numNewPoints = 0;
       
  1609         TInt contourIndex = 0;
       
  1610         
       
  1611         iNewOutline.contours = 0;
       
  1612         iNewOutline.n_contours = iOutline->n_contours;
       
  1613         iNewOutline.contours = (short *)
       
  1614                 User::Alloc(iNewOutline.n_contours * sizeof(short));
       
  1615         
       
  1616         if (0 == iOutline->contours[0]) 
       
  1617             {
       
  1618             iNewOutline.contours[0] = iOutline->contours[0]; // == 0
       
  1619             ++contourIndex;
       
  1620             }
       
  1621         for (TInt i = 1; i < iOutline->n_points; ++i) 
       
  1622             {
       
  1623                 currentTag = FT_CURVE_TAG(iOutline->tags[i]);
       
  1624                 if (FT_CURVE_TAG_CONIC == prevTag && prevTag == currentTag)
       
  1625                     {
       
  1626                     numNewPoints++;
       
  1627                     }
       
  1628                 prevTag = currentTag;
       
  1629                 if (i == iOutline->contours[contourIndex]) 
       
  1630                     {
       
  1631                     iNewOutline.contours[contourIndex] =
       
  1632                         iOutline->contours[contourIndex] + numNewPoints;
       
  1633                     ++contourIndex;
       
  1634                     }
       
  1635             }
       
  1636         
       
  1637         
       
  1638         iNewOutline.n_points = iOutline->n_points + numNewPoints;
       
  1639         iNewOutline.flags = iOutline->flags;
       
  1640         
       
  1641         iNewOutline.points = 0;
       
  1642         iNewOutline.tags = 0;
       
  1643         
       
  1644         iNewOutline.points = (FT_Vector *)
       
  1645             User::Alloc(iNewOutline.n_points * sizeof(FT_Vector));
       
  1646 
       
  1647         if (iNewOutline.contours)
       
  1648             {
       
  1649             iNewOutline.tags = (char *)
       
  1650                 User::Alloc(iNewOutline.n_points * sizeof(char));
       
  1651             }
       
  1652         
       
  1653         // copy the 'points' and 'tags' array, inserting new points
       
  1654         // when necessary.
       
  1655         TInt oldIndex = 0, newIndex = 0;
       
  1656         for ( ; oldIndex < iOutline->n_points; ++oldIndex) 
       
  1657             {
       
  1658             char oldTag = FT_CURVE_TAG(iOutline->tags[oldIndex]);
       
  1659             iNewOutline.points[newIndex] = iOutline->points[oldIndex];
       
  1660             iNewOutline.tags[newIndex] = iOutline->tags[oldIndex];
       
  1661             
       
  1662             if (FT_CURVE_TAG_CONIC == oldTag && 
       
  1663                     oldIndex + 1 < iOutline->n_points) 
       
  1664                 {
       
  1665                 char nextTag = FT_CURVE_TAG(iOutline->tags[oldIndex+1]);
       
  1666                 // insert a new 'on' point when there are two consecutive 
       
  1667                 // 'conic off' points.
       
  1668                 if (oldTag == nextTag)
       
  1669                     {
       
  1670                     newIndex++;
       
  1671                     FT_Vector *cur = &(iOutline->points[oldIndex]);
       
  1672                     FT_Vector *next = &(iOutline->points[oldIndex + 1]);
       
  1673                     iNewOutline.points[newIndex].x = (cur->x + next->x)/2;
       
  1674                     iNewOutline.points[newIndex].y = (cur->y + next->y)/2;
       
  1675                     iNewOutline.tags[newIndex] = FT_CURVE_TAG_ON;
       
  1676                     }
       
  1677                 }
       
  1678             newIndex++;
       
  1679             }
       
  1680         
       
  1681         return 0;
       
  1682         }
       
  1683     
       
  1684 public:
       
  1685     COutlineConvDirector():iProcessor(0), iOutline(0) 
       
  1686         {
       
  1687         // a null constructor
       
  1688         iNewOutline.contours = 0;
       
  1689         iNewOutline.tags = 0;
       
  1690         iNewOutline.points = 0;
       
  1691         }
       
  1692     
       
  1693     ~COutlineConvDirector()
       
  1694         {
       
  1695         User::Free(iNewOutline.contours);
       
  1696         User::Free(iNewOutline.points);
       
  1697         User::Free(iNewOutline.tags);
       
  1698         }
       
  1699     
       
  1700     TInt
       
  1701     ConvertOutline(const FT_Outline &aOutline, MVGCommandProcessor *aProcessor) 
       
  1702         {
       
  1703         if (0 != aOutline.n_contours) 
       
  1704             {
       
  1705             iProcessor = aProcessor;
       
  1706             iOutline = &aOutline;
       
  1707             
       
  1708             MoveFirstOnPointToBeginning(0, iOutline->contours[0]);
       
  1709             TInt i = 0;
       
  1710             for (i = 1; i < iOutline->n_contours; ++i)
       
  1711                 {
       
  1712                 MoveFirstOnPointToBeginning(iOutline->contours[i-1]+1, iOutline->contours[i]);
       
  1713                 }
       
  1714                     
       
  1715             Preprocess();
       
  1716             
       
  1717             ConvertContour(0, iNewOutline.contours[0]);
       
  1718             for (i = 1; i < iNewOutline.n_contours; ++i)
       
  1719                 {
       
  1720                 ConvertContour(iNewOutline.contours[i-1]+1, iNewOutline.contours[i]);
       
  1721                 }
       
  1722             }
       
  1723         else
       
  1724             {
       
  1725 			RDebug::Printf("Zero contour in outline: missing glyph.");
       
  1726             FT_Vector dummyVector;
       
  1727             aProcessor->ProcessCommand(VG_CMD_CLOSE, dummyVector, dummyVector);
       
  1728             }
       
  1729         return KErrNone;
       
  1730         }
       
  1731 };
       
  1732 
       
  1733 
       
  1734 TInt CFreeTypeFontFile::GetGlyphOutline(TInt aFaceIndex, TUint aCode, 
       
  1735         TBool aIsGlyphId, TBool, TAny*& aOutline, TInt &aLength) 
       
  1736     {
       
  1737     // The 4th param 'aHinted' is ignored in this reference implementation.
       
  1738     // Need to add it back and implement accordingly if freetype is used in 
       
  1739     // production code.
       
  1740     CFaceListItem *faceList = LoadFaceL(aFaceIndex);
       
  1741     FT_Face face = faceList->Face();
       
  1742     TUint code = aCode;
       
  1743     if (!aIsGlyphId) 
       
  1744         {
       
  1745         code = FT_Get_Char_Index(face, aCode);
       
  1746         if (0 == code)
       
  1747             {
       
  1748             return KErrNotFound;
       
  1749             }
       
  1750         }
       
  1751     
       
  1752     TInt ret = FT_Load_Glyph(face, code, 
       
  1753             FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM);
       
  1754     
       
  1755     if (0 != ret)
       
  1756         {
       
  1757         return KErrUnknown;
       
  1758         }
       
  1759     
       
  1760     COutlineStringBuilder strBuilder;
       
  1761     if (0 != strBuilder.GetBuffer(aLength)) 
       
  1762         {
       
  1763         FT_Outline &outline = face->glyph->outline;
       
  1764         
       
  1765         COutlineConvDirector d;
       
  1766         d.ConvertOutline(outline, &strBuilder);
       
  1767         }
       
  1768     else
       
  1769         {
       
  1770         return KErrNoMemory;
       
  1771         }
       
  1772 
       
  1773     TUint8 *buf = strBuilder.GetBuffer(aLength);
       
  1774     RDebug::Printf("length of buffer is %d\n", aLength);
       
  1775     RDebug::Printf("Outline for glyph %d: \n", aCode);
       
  1776     RDebug::Printf("%s", buf);
       
  1777     aOutline = (TAny*)buf;
       
  1778     
       
  1779     return KErrNone;
       
  1780     }
       
  1781 TAny* CFreeTypeFontFile::GetTrueTypeTable(TInt& aError, TInt aFaceIndex,
  1287 TAny* CFreeTypeFontFile::GetTrueTypeTable(TInt& aError, TInt aFaceIndex,
  1782 	TUint32 aTag, TInt* aLength)
  1288 	TUint32 aTag, TInt* aLength)
  1783 	{
  1289 	{
  1784 	aError = KErrNone;
  1290 	aError = KErrNone;
  1785 
  1291