4 * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
10 #include "LEGlyphFilter.h"
11 #include "LEGlyphStorage.h"
12 #include "LayoutEngine.h"
13 #include "OpenTypeLayoutEngine.h"
14 #include "ArabicLayoutEngine.h"
15 #include "ScriptAndLanguageTags.h"
16 #include "CharSubstitutionFilter.h"
18 #include "GlyphSubstitutionTables.h"
19 #include "GlyphDefinitionTables.h"
20 #include "GlyphPositioningTables.h"
22 #include "GDEFMarkFilter.h"
24 #include "ArabicShaping.h"
25 #include "CanonShaping.h"
29 le_bool
CharSubstitutionFilter::accept(LEGlyphID glyph
) const
31 return fFontInstance
->canDisplay((LEUnicode
) glyph
);
34 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine
)
36 ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance
*fontInstance
, le_int32 scriptCode
, le_int32 languageCode
,
37 const GlyphSubstitutionTableHeader
*gsubTable
)
38 : OpenTypeLayoutEngine(fontInstance
, scriptCode
, languageCode
, gsubTable
)
40 /**/ fFeatureOrder
= ArabicShaping::getFeatureOrder();
43 ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance
*fontInstance
, le_int32 scriptCode
, le_int32 languageCode
)
44 : OpenTypeLayoutEngine(fontInstance
, scriptCode
, languageCode
)
46 // fFeatureOrder = ArabicShaping::getFeatureOrder();
49 ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
55 // Output: characters, char indices, tags
56 // Returns: output character count
57 le_int32
ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars
[], le_int32 offset
, le_int32 count
, le_int32 max
, le_bool rightToLeft
,
58 LEUnicode
*&/*outChars*/, LEGlyphStorage
&glyphStorage
, LEErrorCode
&success
)
60 if (LE_FAILURE(success
)) {
64 if (chars
== NULL
|| offset
< 0 || count
< 0 || max
< 0 || offset
>= max
|| offset
+ count
> max
) {
65 success
= LE_ILLEGAL_ARGUMENT_ERROR
;
69 glyphStorage
.adoptGlyphCount(count
);
70 glyphStorage
.allocateAuxData(success
);
72 if (LE_FAILURE(success
)) {
73 success
= LE_MEMORY_ALLOCATION_ERROR
;
77 ArabicShaping::shape(chars
, offset
, count
, max
, rightToLeft
, glyphStorage
);
82 void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars
[], le_int32 offset
, le_int32 count
, le_bool reverse
,
83 LEGlyphStorage
&glyphStorage
, LEErrorCode
&success
)
85 if (LE_FAILURE(success
)) {
89 if (chars
== NULL
|| offset
< 0 || count
< 0) {
90 success
= LE_ILLEGAL_ARGUMENT_ERROR
;
94 if (fGPOSTable
!= NULL
) {
95 OpenTypeLayoutEngine::adjustGlyphPositions(chars
, offset
, count
, reverse
, glyphStorage
, success
);
96 } else if (fGDEFTable
!= NULL
) {
97 GDEFMarkFilter
filter(fGDEFTable
);
99 adjustMarkGlyphs(glyphStorage
, &filter
, success
);
101 GlyphDefinitionTableHeader
*gdefTable
= (GlyphDefinitionTableHeader
*) CanonShaping::glyphDefinitionTable
;
102 GDEFMarkFilter
filter(gdefTable
);
104 adjustMarkGlyphs(&chars
[offset
], count
, reverse
, glyphStorage
, &filter
, success
);
108 UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance
*fontInstance
, le_int32 scriptCode
, le_int32 languageCode
)
109 : ArabicOpenTypeLayoutEngine(fontInstance
, scriptCode
, languageCode
)
111 fGSUBTable
= (const GlyphSubstitutionTableHeader
*) CanonShaping::glyphSubstitutionTable
;
112 fGDEFTable
= (const GlyphDefinitionTableHeader
*) CanonShaping::glyphDefinitionTable
;
114 fSubstitutionFilter
= new CharSubstitutionFilter(fontInstance
);
117 UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
119 delete fSubstitutionFilter
;
122 // "glyphs", "indices" -> glyphs, indices
123 le_int32
UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage
&tempGlyphStorage
, LEGlyphStorage
&glyphStorage
, LEErrorCode
&success
)
125 if (LE_FAILURE(success
)) {
129 // FIXME: we could avoid the memory allocation and copy if we
130 // made a clone of mapCharsToGlyphs which took the fake glyphs
132 le_int32 tempGlyphCount
= tempGlyphStorage
.getGlyphCount();
133 LEUnicode
*tempChars
= LE_NEW_ARRAY(LEUnicode
, tempGlyphCount
);
135 if (tempChars
== NULL
) {
136 success
= LE_MEMORY_ALLOCATION_ERROR
;
140 for (le_int32 i
= 0; i
< tempGlyphCount
; i
+= 1) {
141 tempChars
[i
] = (LEUnicode
) LE_GET_GLYPH(tempGlyphStorage
[i
]);
144 glyphStorage
.adoptCharIndicesArray(tempGlyphStorage
);
146 ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars
, 0, tempGlyphCount
, FALSE
, TRUE
, glyphStorage
, success
);
148 LE_DELETE_ARRAY(tempChars
);
150 return tempGlyphCount
;
153 void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars
[], le_int32 offset
, le_int32 count
, le_bool reverse
, le_bool
/*mirror*/, LEGlyphStorage
&glyphStorage
, LEErrorCode
&success
)
155 if (LE_FAILURE(success
)) {
159 if (chars
== NULL
|| offset
< 0 || count
< 0) {
160 success
= LE_ILLEGAL_ARGUMENT_ERROR
;
164 le_int32 i
, dir
= 1, out
= 0;
171 glyphStorage
.allocateGlyphArray(count
, reverse
, success
);
173 for (i
= 0; i
< count
; i
+= 1, out
+= dir
) {
174 glyphStorage
[out
] = (LEGlyphID
) chars
[offset
+ i
];
178 void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars
[], le_int32 offset
, le_int32 count
, le_bool reverse
,
179 LEGlyphStorage
&glyphStorage
, LEErrorCode
&success
)
181 if (LE_FAILURE(success
)) {
185 if (chars
== NULL
|| offset
< 0 || count
< 0) {
186 success
= LE_ILLEGAL_ARGUMENT_ERROR
;
190 GDEFMarkFilter
filter(fGDEFTable
);
192 adjustMarkGlyphs(&chars
[offset
], count
, reverse
, glyphStorage
, &filter
, success
);