graphicsdeviceinterface/gdi/sgdi/GlyphSel.cpp
changeset 183 6a1564a2f3e6
parent 168 2bd88482bfe5
child 194 18f84489a694
--- a/graphicsdeviceinterface/gdi/sgdi/GlyphSel.cpp	Thu Sep 02 21:50:40 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,593 +0,0 @@
-// Copyright (c) 2003-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:
-//
-
-/**
- @file
- @internalComponent
-*/
-
-
-#include <gdi.h>
-#include <openfont.h>
-#include "GlyphSel.h"
-#include "GDIPANIC.h"
-
-
-static const TText16 KLatinGlyph_SoftHyphen = 0x00AD;
-
-
-// 
-//
-// TUtf32Iterator Class definition
-//
-//
-
-
-TUint TUtf32Iterator::UTF16ToTChar(const TText16* a)
-/**
- This routine takes an encoded UTF16 byte array and decodes the
- first character at the start of the array and returns it as a TChar.
- If the char is "not a char" character 0xFFFF results.
-@param a 
- UTF16 byte array to be decoded.
-@param aPr
- Position pointer 'a' derived from, incremented if surragote pairs decoded.
-@return
- The character value in UTF32 format or 0xFFFF it not a character.
-*/
-	{
-	// Is next char a surrogate?
-	if (0xD800 == (a[0] & 0xF800)) 
-		{
-		// Is it a high surrogate in the range D800..DBFF?
-		if (0xD800 == (a[0] & 0xFC00)) 
-			{
-			// Its a high surrogate, is the next char a low surrogate?
-			if (0xDC00 == (a[1] & 0xFC00))
-				{
-				// It's a low surrogate
-				return ((a[0] - 0xd7f7) << 10) + a[1];
-				}
-			else
-				return 0xFFFF;
-			}
-		else
-			return 0xFFFF;
-		}
-	else
-		return a[0];
-	}
-
-
-TUtf32Iterator::TUtf32Iterator(const TText16* aStart, const TText16* aEnd, TInt aStartingIndex)
-/**
- Construct iterator given UTF16 encoded byte array.
-@param aStart
- Start address of the array.
-@param aEnd
- Address of the byte just beyond the end of the array.
-@param aStartingIndex
- Optional UTF16 offset into the array to initialise the current position to.
-@panic EGdiPanic_InvalidInputParam
- Raised when array start if passed the array end.
-*/
-: iStart(aStart), iCurrent(aStart+aStartingIndex), iEnd(aEnd), iChar(0xffff)
-	{
-	GDI_ASSERT_DEBUG(iStart < iEnd, EGdiPanic_InvalidInputParam);
-	
-	if (iCurrent > iEnd) 
-	    iCurrent = iEnd;
-	else if (iCurrent < iStart)
-	    iCurrent = iStart;
-	else
-		{
-		// Sanatise array end checking for an unpaired surrogate value
-		// so that UTF16ToTChar() does not read off the end of the array.
-        if (0xD800 == (iEnd[-1] & 0xFC00))
-			{
-			if (iCurrent == iEnd-1)
-				++iCurrent;
-			else
-				--iEnd;
-			}
-
-		// Setup initial position UTF32 character value 
-		iChar = UTF16ToTChar(iCurrent);
-		}
-	}
-
-
-TChar TUtf32Iterator::Next()
-/**
-Moves the iterator forward to the next valid UTF32 character value.
-@return TChar The next character in the text towards the end.
-@panic EGdiPanic_OutOfText
-Raised when there is no next position to move to.
-*/
-	{
-	GDI_ASSERT_DEBUG(iCurrent < iEnd, EGdiPanic_OutOfText);
-
-    iCurrent += (iChar > 0xffff) ? 2 : 1;
-    if (iCurrent < iEnd)
-	    iChar = UTF16ToTChar(iCurrent);
-	else
-	    iChar = 0xFFFF;  
-	return iChar;
-	}
-
-
-TChar TUtf32Iterator::Prev()
-/**
-Moves the iterator backwards to the next valid UTF32 character value.
-@return TChar The prev character in the text towards the start.
-@panic EGdiPanic_OutOfText Raised when there is no next position to move to.
-*/
-	{
-	GDI_ASSERT_DEBUG(iCurrent >= iStart, EGdiPanic_OutOfText);
-
-    --iCurrent;
-    if (iCurrent >= iStart)
-	    iChar = UTF16ToTChar(iCurrent);
-	else
-	    iChar = 0xFFFF;
-	return iChar; 
-	}
-
-
-void TUtf32Iterator::SetPos(TInt aPos)
-/**
- Moves the iterator to the position specified by array start+offset.
-@param aPos
-  UTF16 offset into the array to set the current position to.
-@panic EGdiPanic_OutOfText
- Raised when there is no next position to move to.
-*/
-	{
-	GDI_ASSERT_DEBUG(iStart+aPos <= iEnd, EGdiPanic_OutOfText);
-	GDI_ASSERT_DEBUG(iStart+aPos >= iStart, EGdiPanic_OutOfText);
-
-	iCurrent = iStart+aPos;
-	iChar = UTF16ToTChar(iCurrent);
-	}
-
-
-TUint TUtf32Iterator::Get(TInt offset)
-/**
- Returns the UTF32 char value at the offset specified. 0xFFFF may be returned
- for unpaired surrogate and noncharacters. Does not change the current 
- position.
-@param offset
- UTF16 offset from current iterator position to get UTF32 char form. 
-@return TChar
- UTF32 char value found at the iterator+offset, or 0xFFFF in error.
-@panic EGdiPanic_OutOfText
- Raised when offset found to be outside the bounds of the original text array.
-*/
-	{
-	GDI_ASSERT_DEBUG(iCurrent+offset >= iStart, EGdiPanic_OutOfText);
-	GDI_ASSERT_DEBUG(iCurrent+offset < iEnd, EGdiPanic_OutOfText);
-	
-	return UTF16ToTChar(iCurrent+offset);
-	}
-
-
-TChar TUtf32Iterator::GetThenNext()
-/**
- Return the UTF32 value at the current position.
-@return TChar
- UTF32 value currently pointed to by iterator.
-@panic EGdiPanic_EndOfText
- Raised when current iterator position is not valid.
-*/
-	{
-	GDI_ASSERT_DEBUG(iCurrent < iEnd, EGdiPanic_OutOfText);
-
-	TChar current(iChar);
-    iCurrent += (iChar > 0xffff) ? 2 : 1;
-    if (iCurrent < iEnd)
-	    iChar = UTF16ToTChar(iCurrent);
-	else
-	    iChar = 0xFFFF;  
-	return current;
-	}
-
-
-TChar TUtf32Iterator::GetThenPrev()
-/**
- Return the UTF32 value at the current position.
-@return TChar
- UTF32 value currently pointed to by iterator.
-@panic EGdiPanic_EndOfText
- Raised when current iterator position is not valid.
-*/
-	{
-	GDI_ASSERT_DEBUG(iCurrent >= iStart, EGdiPanic_OutOfText);
-
-	TChar current(iChar);
-    --iCurrent;
-    if (iCurrent >= iStart)
-	    iChar = UTF16ToTChar(iCurrent);
-	else
-	    iChar = 0xFFFF;
-	return current;
-	}
-	
-	
-TInt TUtf32Iterator::LengthToStart() const
-/**
- Returns the number of TText16 codes between the start point and its
- current position.
-@return TInt
- Number of TText16 characters between array start and current iterator
- position.
-*/
-	{
-	return iCurrent-iStart;
-	}
-
-
-TInt TUtf32Iterator::LengthToEnd() const
-/**
- Returns the number of remaining TText16 codes still ahead of the
- iterator.
-@return TInt
- Number of TText16 characters between array current iterator position
- and the end of the array.
-*/
-	{
-	return iEnd - iCurrent;
-	}
-
-const TText16* TUtf32Iterator::CurrentPosition() const
-	{
-	return iCurrent;
-	}
-
-void TUtf32Iterator::SetCurrentPosition(const TText16* a)
-	{
-	iCurrent = a;
-	}
-
-// 
-//
-// TGlyphSelectionState Class definition
-//
-//
-
-
-/** 
- The Unicode Combining Class values recognised by the
- GlyphSelUtils::CombineLastGlyphToBase method.
-@internalComponent
-*/
-enum TCombiningClass
-	{
-	EArabicFathatan = 27,
-	EArabicDammatan = 28,
-	EArabicKasratan = 29,
-	EArabicFatha = 30,
-	EArabicDamma = 31,
-	EArabicKasra = 32,
-	EArabicShadda = 33,
-	EArabicSukun = 34,
-	ECombineBelowLeftAttached = 200,
-	ECombineBelowAttached = 202,
-	ECombineBelowRightAttached = 204,
-	ECombineLeftAttached = 208,
-	ECombineRightAttached = 210,
-	ECombineAboveLeftAttached = 212,
-	ECombineAboveAttached = 214,
-	ECombineAboveRightAttached = 216,
-	ECombineBelowLeft = 218,
-	ECombineBelow = 220,
-	ECombineBelowRight = 222,
-	ECombineLeft = 224,
-	ECombineRight = 226,
-	ECombineAboveLeft = 228,
-	ECombineAbove = 230,
-	ECombineAboveRight = 232
-	};
-
-
-/**
- This method is called to attach (by adjusing its bounding box) the current end
- glyph in the output array of iParam to the base glyph bounding box based on
- the Unicode combining class of the character.
-@param aGss
- The general input/output glyph selection data for the routine.
-@param aGss.iOutput
- Input: Glyph cluster with last glyph an actual combining character. Output:
- Bounding box of last glyph adjusted according to char combining class.
-@param aFirstDiacritic
- Which character in the output array to treat as the first diacritic of the
- cluster. Usually 1, but can be more if the base class is a ligature.
-*/
-void TGlyphSelectionState::CombineLastGlyphToBase(const TRect& aBase, TInt aFirstDiacritic)
-	{
-	// Get the bounds of all the base characters.
-	TRect base = aBase;
-	int last = iParam.iOutputGlyphs-1;
-	for (int i = aFirstDiacritic; i < last; i++)
-		base.BoundingRect(iParam.iOutput[i].iBounds);
-
-	// Calculate the attachment points.
-	TRect& r = iParam.iOutput[last].iBounds;
-	int w = r.Width();
-	int h = r.Height();
-	int t = r.iTl.iY;
-	int l = r.iTl.iX;
-	int left = base.iTl.iX;
-	int center = base.iTl.iX + (base.Width() - w) / 2;
-	int right = base.iBr.iX - w;
-	int below = base.iBr.iY;
-	int above = base.iTl.iY - h;
-	int left_of = left - w;
-	int right_of = right + w;
-	int xGap = 1;
-	int yGap = iFont->HeightInPixels()/10;
-	
-	// Select attachment based on combining class.
-	switch (iCombCls)
-		{
-		case ECombineBelowLeftAttached:
-			t = below;
-			l = left;
-			break;
-		case ECombineBelowAttached:
-			t = below;
-			l = center;
-			break;
-		case ECombineBelowRightAttached:
-			t = below;
-			l = right;
-			break;
-		case ECombineLeftAttached:
-			l = left_of;
-			break;
-		case ECombineRightAttached:
-			l = right_of;
-			break;
-		case ECombineAboveLeftAttached:
-			t = above;
-			l = left;
-			break;
-		case ECombineAboveAttached:
-			t = above;
-			l = center;
-			break;
-		case ECombineAboveRightAttached:
-			t = above;
-			l = right;
-			break;
-		case ECombineBelowLeft:
-			t = below + yGap;
-			l = left;
-			break;
-		case ECombineBelow:
-		case EArabicKasratan:
-		case EArabicKasra:
-			t = below + yGap;
-			l = center;
-			break;
-		case ECombineBelowRight:
-			t = below + yGap;
-			l = right;
-			break;
-		case ECombineLeft:
-			l = left_of - xGap;
-			break;
-		case ECombineRight:
-			l = right_of + xGap;
-			break;
-		case ECombineAboveLeft:
-			t = above - yGap;
-			l = left;
-			break;
-		case ECombineAbove:
-		case EArabicFathatan:
-		case EArabicDammatan:
-		case EArabicFatha:
-		case EArabicDamma:
-		case EArabicShadda:
-		case EArabicSukun:
-			t = above - yGap;
-			l = center;
-			break;
-		case ECombineAboveRight:
-			t = above - yGap;
-			l = right;
-			break;
-		default:
-			l = center;
-			break;
-		}
-
-	// Adjust the bounding box of the last glyph to fix position
-	// based on the characters combining class. For speed, do directly.
-	// r.SetRect(l,t,l + w,t + h);
-	r.iTl.iX = l;
-	r.iTl.iY = t;
-	r.iBr.iX = l+w;
-	r.iBr.iY = t+h;
-	}
-
-
-TBool TGlyphSelectionState::AppendGlyphToCluster(TUint aCode)
-/**
- This common method is used by glyph selector classes to add a glyph to
- the end of the aGss.iParam output field filling in all the glyph info 
- needed.
-@param aCode
- The Unicode character for which a glyph should be appended.
-@param aGss
- The general input/output glyph selection data for the routine. 
-@return TBool
- ETrue when successful, EFalse when failure occurs e..g no char data, overflow
-*/
-	{
-	// Setup reference to next free glyph record we need to update.
-	GDI_ASSERT_DEBUG(iParam.iOutputGlyphs < CFont::TPositionParam::EMaxOutputGlyphs, 
-		EGdiPanic_InvalidInputParam);
-	   
-	CFont::TPositionParam::TOutput* output = iParam.iOutput+iParam.iOutputGlyphs;
-
-	// Retrieve the glyph details from the Font. Essential to proceed, abort
-	// if not available.
-	TOpenFontCharMetrics metrics;
-	if (iFont->GetCharacterData(aCode, metrics, output->iBitmap, 
-		output->iBitmapSize) == CFont::ENoCharacterData)
-		return EFalse;
-
-	// Set code point of glyph in output record.
-	output->iCode = aCode;
-	
-	// Set the glyph's bounds in the output record and record pen advancement.
-	if (iParam.iDirection == CFont::EVertical)
-		{
-		metrics.GetVertBounds(output->iBounds);
-		iAdvance.iHeight = Max(iAdvance.iHeight, metrics.VertAdvance());
-		}
-	else
-		{
-		metrics.GetHorizBounds(output->iBounds);
-		iAdvance.iWidth = Max(iAdvance.iWidth, metrics.HorizAdvance());
-		}
-
-	// Next adjust the glyph's bounding box to offset it from the pen
-	// position (origin of drawing). For speed increment attributes directly.
-	// output->iBounds.Move(aGss.iParam.iPen);
-	output->iBounds.iTl.iX += iParam.iPen.iX;
-	output->iBounds.iBr.iX += iParam.iPen.iX;
-	output->iBounds.iTl.iY += iParam.iPen.iY;
-	output->iBounds.iBr.iY += iParam.iPen.iY;
-	
-	// Before we exit with success, increment the glyph array counter.
-	// for the new glyph we've added here.
-	iParam.iOutputGlyphs++;
-	return ETrue;
-	}
-
-
-// 
-//
-// GlyphSelector_SoftHyphen Class definition
-//
-//
-
-TBool GlyphSelector_SoftHyphen::Process(TGlyphSelectionState& aGss, RShapeInfo&) 
-/**
-@see GlyphSelUtils 
- See this class for the method description.
-*/
-	{
- 	aGss.iText.Next();
-	if (!aGss.iText.AtEnd())
-		{
-		// Here we skip & don't output hyphen since its not at the end a line.
-		aGss.iPen = TGlyphSelectionState::EPenAdvance_No;
-		}
-	else
-		{
-		// If we reach here we must output hyphen.
-		if (!aGss.AppendGlyphToCluster(KLatinGlyph_SoftHyphen))
-			return EFalse;
-		
-		aGss.iPen = TGlyphSelectionState::EPenAdvance_Yes;
-		}
-
-	// Logic to determine if we are now at the end of the glyph cluster.
-	// Default logic, based on whether a combining mark follows or not.
-	aGss.iClusterState = 
-		(!aGss.iText.AtEnd() &&
-			((aGss.iText.Get().GetCategory() & 0xF0) == TChar::EMarkGroup)) ?
-			TGlyphSelectionState::EGClusterNotComplete : TGlyphSelectionState::EGClusterComplete;
-
-	return ETrue;
-	}
-
-
-// 
-//
-// GlyphSelector_Default Class definition
-//
-//
-
-
-TBool GlyphSelector_Default::Process(TGlyphSelectionState& aGss, RShapeInfo&) 
-/**
-@see GlyphSelUtils 
- See this class for the method description.
-*/
-	{
-	
-	// In this method we always output the glyph.
-	if (!aGss.AppendGlyphToCluster(aGss.iText.GetThenNext()))
-		return EFalse;
-
-	// Adjust glyph's bounds further to position this character if it is a
-	// combining mark
-	if (aGss.IsCombiningClass())
-		{
-		aGss.iPen = TGlyphSelectionState::EPenAdvance_No;
-		
-		TRect baseBounds(aGss.iParam.iOutput[0].iBounds);
-		// Get first character in this glyph cluster. In this default process function, the iCode should 
-		// be Unicode Point Code.  
-		TChar startChar = TChar(aGss.iParam.iOutput[0].iCode);
-		// Character index in the output array to treat as the first diacritic of the
-		// cluster. It will be used as first character for combine to. usually 1, but when
-		// the cluster starts with a combining mark, it should be set to 0.  
-		TInt indexOfFirstCombining = 1; 
-		TInt startCharCat = startChar.GetCategory() & 0xF0;
-		
-		// if the first character in this cluster is a combining mark or a graphically empty character, 
-		// (such as a space Character0x0020), a fake bound, formed from the Ascent of the font, will be 
-		// used for combining
-		if ((startCharCat == TChar::EMarkGroup) || baseBounds.Size() == TSize(0,0)) 
-			{
-			// Determine the height of the combining glyph.
-			TInt glyphHeight = 0;
-			if (aGss.iParam.iOutputGlyphs == 1)
-				{
-				glyphHeight = aGss.iParam.iOutput[0].iBitmapSize.iHeight;
-				}
-			else
-				{
-				glyphHeight = aGss.iParam.iOutput[1].iBitmapSize.iHeight;
-				}
-			// Adjust Y values to a ficticious but reasonable range for it to combine to using the glyph height to adjust correctly below the font ascent.
-			baseBounds.iTl.iY = aGss.iParam.iPen.iY - aGss.iFont->AscentInPixels() + glyphHeight; //modest ascender
-			baseBounds.iBr.iY = aGss.iParam.iPen.iY; //No descender
-			}
-		
-		if (startCharCat == TChar::EMarkGroup)
-			indexOfFirstCombining = 0;
-								
-		aGss.CombineLastGlyphToBase(baseBounds, indexOfFirstCombining);
-		aGss.iGlyphPostCombine = TGlyphSelectionState::EGPostCombine_Yes;
-		}	
-	else
-		aGss.iPen = TGlyphSelectionState::EPenAdvance_Yes;
-
-	// Logic to determine if we are now at the end of the glyph cluster.
-	// Default logic, based on whether a combining mark follows or not.
-	aGss.iClusterState = 
-		(!aGss.iText.AtEnd() &&
-		 ((aGss.iText.Get().GetCategory() & 0xF0) == TChar::EMarkGroup)) ?
-			TGlyphSelectionState::EGClusterNotComplete : TGlyphSelectionState::EGClusterComplete;
-
-	return ETrue;
-	}
-