Home | History | Annotate | Download | only in layout
      1 
      2 /*
      3  *
      4  * (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
      5  *
      6  */
      7 
      8 #include "LETypes.h"
      9 #include "LayoutEngine.h"
     10 #include "OpenTypeLayoutEngine.h"
     11 #include "IndicLayoutEngine.h"
     12 #include "ScriptAndLanguageTags.h"
     13 
     14 #include "GlyphSubstitutionTables.h"
     15 #include "GlyphDefinitionTables.h"
     16 #include "GlyphPositioningTables.h"
     17 
     18 #include "GDEFMarkFilter.h"
     19 #include "LEGlyphStorage.h"
     20 
     21 #include "IndicReordering.h"
     22 
     23 U_NAMESPACE_BEGIN
     24 
     25 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
     26 
     27 IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
     28                     le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
     29     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
     30 {
     31 	if ( version2 ) {
     32 		fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
     33 	} else {
     34         fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
     35 	}
     36 	fFeatureOrder = TRUE;
     37     fVersion2 = version2;
     38     fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
     39 }
     40 
     41 IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
     42     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMPreFixups(NULL)
     43 {
     44     fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
     45     fFeatureOrder = TRUE;
     46 	fVersion2 =  FALSE;
     47 }
     48 
     49 IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine()
     50 {
     51     // nothing to do
     52 }
     53 
     54 // Input: characters, tags
     55 // Output: glyphs, char indices
     56 le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
     57                     LEGlyphStorage &glyphStorage, LEErrorCode &success)
     58 {
     59     if (LE_FAILURE(success)) {
     60         return 0;
     61     }
     62 
     63     if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
     64         success = LE_ILLEGAL_ARGUMENT_ERROR;
     65         return 0;
     66     }
     67 
     68     le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success);
     69 
     70     if (LE_FAILURE(success)) {
     71         return 0;
     72     }
     73 
     74     if (fVersion2) {
     75         IndicReordering::finalReordering(glyphStorage,retCount);
     76         IndicReordering::applyPresentationForms(glyphStorage,retCount);
     77         OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
     78     } else {
     79         IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
     80     }
     81     return retCount;
     82 }
     83 
     84 // Input: characters
     85 // Output: characters, char indices, tags
     86 // Returns: output character count
     87 le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
     88         LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
     89 {
     90     if (LE_FAILURE(success)) {
     91         return 0;
     92     }
     93 
     94     if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
     95         success = LE_ILLEGAL_ARGUMENT_ERROR;
     96         return 0;
     97     }
     98 
     99     le_int32 worstCase = count * IndicReordering::getWorstCaseExpansion(fScriptCode);
    100 
    101     outChars = LE_NEW_ARRAY(LEUnicode, worstCase);
    102 
    103     if (outChars == NULL) {
    104         success = LE_MEMORY_ALLOCATION_ERROR;
    105         return 0;
    106     }
    107 
    108     glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success);
    109     glyphStorage.allocateAuxData(success);
    110 
    111     if (LE_FAILURE(success)) {
    112         LE_DELETE_ARRAY(outChars);
    113         return 0;
    114     }
    115 
    116     // NOTE: assumes this allocates featureTags...
    117     // (probably better than doing the worst case stuff here...)
    118 
    119     le_int32 outCharCount;
    120     if (fVersion2) {
    121         outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage);
    122     } else {
    123         outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success);
    124     }
    125 
    126     if (LE_FAILURE(success)) {
    127         LE_DELETE_ARRAY(outChars);
    128         return 0;
    129     }
    130 
    131     glyphStorage.adoptGlyphCount(outCharCount);
    132     return outCharCount;
    133 }
    134 
    135 U_NAMESPACE_END
    136