[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CALL FOR HELP ON ABIWORD



 لا أعرف لماذا لا يستقل بريدك رسالتي، يعطيني هذه الرسالة:
<lumina at silverpen dot de>:
address: {تمت إزالته}
quota: 100000000
failed to write delivered to line errno=28



  شكراً عرفات،
  مرفق صورة لآخر ما توصلت إليه مع الرقعة اللازمة لذلك.
  الصورة هنا:
  http://mhdyousif.host.sk/files/abiword_shaping.jpg
  لاحظ أن هذه الرقعة يجب أن تطبق على الـsnapshot الموجودة هنا:
http://abiword.pchasm.org/source/

abi.HEAD.abiword-cvs.src.tgz ( 8.5M ) last updated: Wednesday, 26-May-2004 
16:00:42 PDT
 ستواجهك مشكلة هي أن الـsnapshot ت عملها على الويندوز وبالتالي فكل ملفاتها
  تحتوي على علامات الM المزعجة ولذلك يحب عمل الآتي قبل تطبيق الرقعة.
cd abi/src/af/gr/xp
dos2unix *
  أو مع كل الملفات.
 بعد ذلك يمكنك تطبيق الرقعة
cd abi/src/af/gr/xp
cd ../../../../..               "بحيث يحتوي الدليل الحالي على الدليل abi"
patch -p0 < abiword_shaping.patch

  لاحظ أنه ما زالت هناك مشاكل بسيطة مع الألف واللام والـligatures بشكل عام،
  سأحاول حلها إن شاء الله.

-- 
Mohammed Yousif
Egypt












Common subdirectories: abi.orig/src/af/gr/xp/CVS and abi/src/af/gr/xp/CVS
Only in abi/src/af/gr/xp: GNUmakefile.in
diff -u abi.orig/src/af/gr/xp/gr_ContextGlyph.cpp abi/src/af/gr/xp/gr_ContextGlyph.cpp
--- abi.orig/src/af/gr/xp/gr_ContextGlyph.cpp	2004-06-13 15:17:24.000000000 +0300
+++ abi/src/af/gr/xp/gr_ContextGlyph.cpp	2004-06-13 15:18:57.000000000 +0300
@@ -17,7 +17,6 @@
  * 02111-1307, USA.
  */
 
-
 #include <stdlib.h>
 #include <string.h>
 
@@ -362,7 +361,7 @@
 	for(UT_uint32 i = 1; i < NrElements(s_ligature) - 1; i++)
 	{
 		if(s_ligature[i].code_low != iLow
-		   && (s_bLatinLigatures || iLow < LATIN_LIGATURES_FIRST
+		   && (!s_bLatinLigatures || iLow < LATIN_LIGATURES_FIRST
 			                     || iLow > LATIN_LIGATURES_LAST))
 		{
 			pRange = new UCSRange;
@@ -378,7 +377,7 @@
 		}
 
 		if(s_ligature[i+1].code_low == s_ligature[i].code_low + 1
-		   || (!s_bLatinLigatures && s_ligature[i+1].code_low >= LATIN_LIGATURES_FIRST
+		   || (s_bLatinLigatures && s_ligature[i+1].code_low >= LATIN_LIGATURES_FIRST
 			                      && s_ligature[i+1].code_low <= LATIN_LIGATURES_LAST))
 		{
 			iLow++;
@@ -389,9 +388,10 @@
 	// now handle the last element
 	pRange = new UCSRange;
 	UT_return_if_fail(pRange);
+	
 	pRange->low = iLow + 1;
 	pRange->high = 0xffffffff;
-
+	
 	s_noLigature.addItem(pRange);
 	xxx_UT_DEBUGMSG(("No Ligature table: adding {0x%04x, 0x%04x}\n",
 				 pRange->low, pRange->high));
@@ -640,10 +640,12 @@
 	{0x0000, 0x05ff},
 
 	// Arabic
-	{0x0622, 0x0625},
-	{0x0627, 0x0627},
-	{0x062f, 0x0632},
-	{0x0648, 0x0648},
+	{0x0621, 0x0625}, // HAMZA, ALEF_MADDA, ALEF_HAMZA_ABOVE, WAW_HAMZA and ALEF_HAMZA_BELOW
+	{0x0627, 0x0627}, // ALEF
+	{0x0629, 0x0629}, // TEH_MARBUTA
+	{0x0630, 0x0632},  // THAL, REH and ZAIN
+	{0x062f, 0x062f}, // DAL
+	{0x0648, 0x0648}, // WAW
 	{0x2000, 0x2fff}
 };
 
@@ -655,7 +657,7 @@
 	{0x0000, 0x05cf},
 
 	// Arabic
-	{0x0621, 0x0621},
+	{0x0621, 0x0621}, // HAMZA
 	{0x2000, 0x2fff}
 };
 
@@ -680,6 +682,7 @@
 	{0x05C4,0x05C4},
 
 	// Arabic overstriking characters
+	{0x060C,0x060C},
 	{0x064B,0x0655},
 	{0x06D6,0x06E8},
 	{0x06EA,0x06ED},
@@ -689,6 +692,7 @@
 
 	// UCS_LIGATURE_PLACEHOLDER
 	{0xf854, 0xf854}
+	//{0xfeff, 0xfeff}
 };
 
 // following three functions determine if shaping and ligature
@@ -755,6 +759,7 @@
 			return true;
 	}
 
+
 	return UT_isWordDelimiter(c,f,p);
 }
 
@@ -1154,12 +1159,15 @@
 
 	UT_uint32 pos = text.getPosition();
 	UT_UCS4Char current = text[pos + offset];
-
+	
 	UT_return_val_if_fail(text.getStatus() == UTIter_OK, GC_ISOLATE);
 		
 	UT_UCS4Char next;
 	++text;
 	next = text.getStatus() == UTIter_OK ? text.getChar() : 0;
+	// if next is a space, don't consider it in shaping
+	if (next == UCS_SPACE)
+	  next = 0;
 	
 	UT_UCS4Char prev;
 	text.setPosition(pos + offset - 1);
@@ -1178,9 +1186,11 @@
 	if(!next && prev)
 	{
 #ifndef NO_BIDI_SUPPORT
+
 		// text is pointing at prev, move one char to the left
-		bPrevWD = isNotJoiningWithNext(prev, current, prev2);
-		
+		//bPrevWD = isNotJoiningWithNext(prev, current, prev2);
+		bPrevWD = isNotJoiningWithPrev(current, next, prev) ||
+		                    isNotJoiningWithNext(prev, current, prev2);
 		if(bPrevWD)
 			return GC_ISOLATE;
 		else
@@ -1204,7 +1214,13 @@
 					 s_comp_ignore))
 	{
 		myNext = (++text).getChar();
+		if (text.getStatus() == UTIter_OutOfBounds)
+		  myNext = 0;
 	}
+
+	// if myNext is a space, don't consider it in shaping
+	if (myNext == UCS_SPACE)
+	  myNext = 0;
 #endif
 	
 	UT_UCS4Char myNext2 = UCS_SPACE;
@@ -1224,8 +1240,9 @@
 	if(!prev && myNext)
 	{
 #ifndef NO_BIDI_SUPPORT
-		bNextWD = isNotJoiningWithPrev(myNext, myNext2, UCS_UNKPUNK);
-		if(bNextWD)
+		bNextWD = !isNotJoiningWithNext(current, myNext, prev) &&
+		                    !isNotJoiningWithPrev(myNext, myNext2, current);
+		if(!bNextWD)
 			return GC_ISOLATE;
 		else
 			return GC_INITIAL;
@@ -1237,7 +1254,8 @@
 	if(prev && !myNext)
 	{
 #ifndef NO_BIDI_SUPPORT
-		bPrevWD = isNotJoiningWithNext(prev, current, prev2);
+		bPrevWD = isNotJoiningWithPrev(current, next, prev) ||
+		                    isNotJoiningWithNext(prev, current, prev2);
 		if(bPrevWD)
 			return GC_ISOLATE;
 		else
@@ -1250,8 +1268,11 @@
 					 *code,*prev, *myNext,myNextNext));
 
 #ifndef NO_BIDI_SUPPORT
-	bPrevWD = isNotJoiningWithNext(prev, current, prev2);
-	bNextWD = isNotJoiningWithPrev(myNext, myNext2, UCS_UNKPUNK);
+	bPrevWD = isNotJoiningWithPrev(current, next, prev) ||
+	                    isNotJoiningWithNext(prev, current, prev2);
+	
+	bNextWD = isNotJoiningWithNext(current, myNext, prev) ||
+	                    isNotJoiningWithPrev(myNext, myNext2, current);
 #else
 	bPrevWD = UT_isWordDelimiter(prev,current,prev2);
 	bNextWD = UT_isWordDelimiter(myNext,myNext2,UCS_UNKPUNK);
@@ -1260,14 +1281,14 @@
 	if(!bPrevWD && !bNextWD)
 		return GC_MEDIAL;
 
-	// if only *next is, than final form is needed
-	if(bNextWD)
-		return GC_FINAL;
-
-	// if *prev is, the initial form is needed
-	if(bPrevWD)
+	// if only *next is, than initial form is needed
+	if(!bNextWD)
 		return GC_INITIAL;
 
+	// if *prev is, the final form is needed
+	if(!bPrevWD)
+		return GC_FINAL;
+
 	// if we got here, both are delimiters, which means stand alone form is needed
 	return GC_ISOLATE;
 }
@@ -1298,15 +1319,17 @@
 
 	bool bLigature = false;
 	bool bContextSensitive = false;
-	
 	for(UT_uint32 i = 0; i < len; i++)
 	{
 		LigatureSequence     Lig;
 		const LetterData   * pLet = 0;
 		const LigatureData * pLig = 0;
-		GlyphContext         context = GC_NOT_SET;
+		GlyphContext         context1 = GC_NOT_SET;
+		GlyphContext         context2 = GC_NOT_SET;
 		
 		current = text[pos + i];
+		
+		
 		UT_return_val_if_fail(text.getStatus() == UTIter_OK, GRSR_Error);
 		
 		//get the current context
@@ -1327,7 +1350,6 @@
 		// check for a ligature form
 		bool bFirstInLig = !isNotFirstInLigature(current);
 		bLigature |= bFirstInLig;
-		
 		if(nextL && bFirstInLig)
 		{
 			Lig.next = nextL;
@@ -1339,13 +1361,16 @@
 													  sizeof(LigatureData),
 													  s_comp_lig));
 		}
-			
+
 		if(pLig)
 		{
 			// we need the context of the whole pair not just of this
 			// character
 			glyph2 = nextL;
 			next = text[pos + i + 2];
+			// if next is a space, don't consider it in shaping
+			if (next == UCS_SPACE)
+	  			next = 0;
 			
 			xxx_UT_DEBUGMSG(("GR_ContextGlyph::render: 0x%x, 1st of lig.\n", *code));
 
@@ -1355,26 +1380,31 @@
 			{
 				bContextSensitive = true;
 				text.setPosition(pos + i);
-				context = _evalGlyphContext(text);
 				
-				switch (context)
-				{
-					case GC_INITIAL:
-						glyph = pLig->initial;
-						break;
-					case GC_MEDIAL:
-						glyph = pLig->medial;
-						break;
-					case GC_FINAL:
-						glyph = pLig->final;
-						break;
-					case GC_ISOLATE:
-						glyph = pLig->alone;
-						break;
-					default:
-						UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
+				//UT_TextIterator textC = text.makeCopy();
+				//prev (pos+i pos+i+1) next
+				
+				context1 = _evalGlyphContext(text);
+				text.setPosition(pos + i + 1);
+				context2 = _evalGlyphContext(text);
+				if ((context1 == GC_ISOLATE || context1 == GC_INITIAL) &&
+				    (context2 == GC_MEDIAL)
+				    ) {
+					glyph = pLig->initial;
+				} else if ((context1 == GC_MEDIAL) &&
+				              (context2 == GC_MEDIAL)
+				             ) {
+					glyph = pLig->medial;
+				} else if ((context1 == GC_MEDIAL) &&
+				              (context2 == GC_ISOLATE || context2 == GC_FINAL)
+				             ) {
+					glyph = pLig->final;
+				} else if ((context1 == GC_ISOLATE || context1 == GC_INITIAL) &&
+				              (context2 == GC_ISOLATE || context2 == GC_FINAL)
+				             ) {
+					glyph = pLig->alone;
 				}
-
+				
 				if(glyph == 1)
 				{
 					// no special form exists in this context, process
@@ -1394,25 +1424,29 @@
 
 
 			bool bGlyphAvailable = (isGlyphAvailable == NULL || isGlyphAvailable(glyph, (void*)fparam));
-			
 			if(!bGlyphAvailable)
 			{
 				UT_DEBUGMSG(("GR_ContextGlyph::render [1a] glyph 0x%x not present in font\n",
 							 glyph));
-				// we need to use the original glyphs; glyph2 is
-				// already set
-				glyph = current;
+							 
+				// deal with it like an ordinary letter
+				goto ligature_form_missing;
+				
 			}
 			else
 			{
 				// just need to set glyph2 to the placement marker
 				glyph2 = UCS_LIGATURE_PLACEHOLDER;
+				//glyph2 = 0xFEFF;
+				//glyph2 = 0x2002;
+				//glyph2 = glyph;;
 			}
 			
 			
 			
 			if(glyph != 1) //first part of a ligature
 			{
+			
 				// we set both this and the next char if we can
 				if(bGlyphAvailable)
 				{
@@ -1438,16 +1472,16 @@
 
 					*dst_ptr++ = s_cDefaultGlyph;
 				}
-
 				
 				continue;
+				
 			}
 			// if we got here, the glyph was 1, which means this form is to be just
 			// treated as an ordinary letter, also if this was a first part of the ligature
 			// we already know its context, but not if it was a second part of lig.
 		}
 		ligature_form_missing:
-		
+
 		// if we have no pLig we are dealing with an ordinary
 		// letter
 		if(!isNotContextSensitive(current))
@@ -1459,7 +1493,7 @@
 													sizeof(LetterData),
 													s_comp));
 		}
-			
+
 		// if we have no pLet, it means the letter has only one form
 		// last thing to do is to deal with mirror characters
 		if(!pLet)
@@ -1494,13 +1528,13 @@
 
 		// if we got this far, we are dealing with a context sensitive character
 		bContextSensitive = true;
-		if(context == GC_NOT_SET)
+		if(context1 == GC_NOT_SET)
 		{
 			text.setPosition(pos + i);
-			context = _evalGlyphContext(text);
+			context1 = _evalGlyphContext(text);
 		}
-		
-		switch (context)
+
+		switch (context1)
 		{
 			case GC_INITIAL:
 				glyph = pLet->initial;
@@ -1548,7 +1582,7 @@
 			}
 		}
 	}
-
+	
 	if(bLigature && !bContextSensitive)
 		return GRSR_Ligatures;
 	
Only in abi/src/af/gr/xp: gr_ContextGlyph.cpp~
diff -u abi.orig/src/af/gr/xp/gr_Graphics.cpp abi/src/af/gr/xp/gr_Graphics.cpp
--- abi.orig/src/af/gr/xp/gr_Graphics.cpp	2004-06-13 15:17:24.000000000 +0300
+++ abi/src/af/gr/xp/gr_Graphics.cpp	2004-06-13 08:48:34.000000000 +0300
@@ -924,7 +924,6 @@
 
 		pRI->m_iBufferSize = si.m_iLength + 1;
 	}
-
 	pRI->m_iLength = si.m_iLength;
 	pRI->m_iTotalLength = si.m_iLength;
 	pRI->m_eScriptType = si.m_pItem->getType();
@@ -945,7 +944,6 @@
 												si.m_iVisDir,
 												GR_Font::s_doesGlyphExist, si.m_pFont);
 	}
-
 	pRI->m_eState = GRSR_BufferClean;
 	
 	if(pRI->m_eShapingResult == GRSR_Error)
@@ -1059,11 +1057,12 @@
    The output starts at ri.m_iOffset, is ri.m_iLength
    long and the drawing starts at ri.m_xoff, ri.m_yoff
 */
+#include <iostream>
 void GR_Graphics::renderChars(GR_RenderInfo & ri)
 {
 	UT_return_if_fail(ri.getType() == GRRI_XP);
 	GR_XPRenderInfo & RI = (GR_XPRenderInfo &)ri;
-
+std::cout << "Rendered Length: " << RI.m_iLength << std::endl;
 	drawChars(RI.s_pCharBuff,RI.m_iOffset,RI.m_iLength,RI.m_xoff,RI.m_yoff,RI.s_pAdvances);
 
 	
Only in abi/src/af/gr/xp: gr_Graphics.cpp~
diff -u abi.orig/src/af/gr/xp/gr_RenderInfo.cpp abi/src/af/gr/xp/gr_RenderInfo.cpp
--- abi.orig/src/af/gr/xp/gr_RenderInfo.cpp	2004-06-13 15:17:24.000000000 +0300
+++ abi/src/af/gr/xp/gr_RenderInfo.cpp	2004-06-13 15:13:23.000000000 +0300
@@ -492,11 +492,10 @@
 
 	// calculate advances from the pre-processed buffer
 	_calculateCharAdvances();
-
 	s_pOwner = this;
 }
 
-
+#include <iostream>
 void GR_XPRenderInfo::_stripLigaturePlaceHolders()
 {
 	UT_return_if_fail(m_iLength <= m_iBufferSize && m_pText);
@@ -530,7 +529,6 @@
 		// m is the logical offeset corresponding to the visual offest i
 		// UT_sint32 m = bReverse ? len - i - 1 : i;
 		UT_sint32 m = i;
-
 		if(m_pChars[i] != UCS_LIGATURE_PLACEHOLDER)
 		{
 			// ordinary character, just copy it and set the width as
@@ -538,6 +536,9 @@
 			s_pCharBuff[j] = m_pChars[i];
 
 			if(bReverse)
+				// FIXME: the width of the ligature is not necessarily the width of the first
+				//              character of the ligature plus the width of the second.
+				//               The width of the ligature glyph should be measure and used instead.
 				s_pWidthBuff[j] += m_pWidths[m];
 			else
 				s_pWidthBuff[j] = m_pWidths[m];
@@ -545,6 +546,7 @@
 		}
 		else
 		{
+			
 			// we will remember whether this ligature is split by the
 			// selection for later use
 			bool bSplitLigature = false;
@@ -553,7 +555,7 @@
 			// ligature in logical coordinances; j is visual offset
 			// into our output buffer
 			UT_uint32 iSplitOffset = bReverse ? m_iLength - j - 1: j;
-
+/*
 			// scroll through the offset array; the offsets define the
 			// segments into which the run is split by the selection
 			// NB: there is always one more (dummy) offset than iOffsetCount
@@ -635,7 +637,7 @@
 				// placeholder from the string
 				m_pSegmentOffset[k]--;
 			}
-
+			*/
 			if(!bSplitLigature)
 			{
 				// we have a ligature which is either completely
@@ -648,12 +650,21 @@
 					// the first part of the ligature will come at the j
 					// index, we want to include the half width of the
 					// second character
-					s_pWidthBuff[j] = m_pWidths[m];
+					
+					// FIXME: the width of the ligature is not necessarily the width of the first
+					//              character of the ligature plus the width of the second.
+					s_pWidthBuff[j-1] = m_pWidths[m+1];
+					
 				}
-
 				j--;
 				m_iLength--;
-
+				// FIXME: For some reason m_iLength got incremented while in GR_Graphics::renderChars if it
+				//              is decremented here!!
+				
+				// I wanted to use FEFF for that, but it got drawn as a square, so I had to use a space to get
+				// around the above problem.
+        			s_pCharBuff[m_iLength] = UCS_SPACE;
+				
 				if(j >= 0 && !bReverse)
 				{
 					s_pWidthBuff[j] += m_pWidths[m];
@@ -661,6 +672,7 @@
 			}
 		}
 	}
+std::cout << "Len: " << m_iLength << std::endl;
 }
 
 
Only in abi/src/af/gr/xp: gr_RenderInfo.cpp~