[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: CALL FOR HELP ON ABIWORD
- To: Arafat Medini <lumina at silverpen dot de>
- Subject: Re: CALL FOR HELP ON ABIWORD
- From: Mohammed Yousif <mhdyousif at gmx dot net>
- Date: Sun, 13 Jun 2004 15:53:10 +0300
- Cc: General Arabization Discussion <general at arabeyes dot org>
- User-agent: KMail/1.6.1
لا أعرف لماذا لا يستقل بريدك رسالتي، يعطيني هذه الرسالة:
<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~