1/* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26/* 27 * 28 * (C) Copyright IBM Corp. 2002-2013 - All Rights Reserved 29 * 30 */ 31 32#include "LETypes.h" 33#include "LEGlyphStorage.h" 34#include "MPreFixups.h" 35 36U_NAMESPACE_BEGIN 37 38struct FixupData 39{ 40 le_int32 fBaseIndex; 41 le_int32 fMPreIndex; 42}; 43 44MPreFixups::MPreFixups(le_int32 charCount) 45 : fFixupData(NULL), fFixupCount(0) 46{ 47 fFixupData = LE_NEW_ARRAY(FixupData, charCount); 48} 49 50MPreFixups::~MPreFixups() 51{ 52 LE_DELETE_ARRAY(fFixupData); 53 fFixupData = NULL; 54} 55 56void MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex) 57{ 58 // NOTE: don't add the fixup data if the mpre is right 59 // before the base consonant glyph. 60 if (baseIndex - mpreIndex > 1) { 61 fFixupData[fFixupCount].fBaseIndex = baseIndex; 62 fFixupData[fFixupCount].fMPreIndex = mpreIndex; 63 64 fFixupCount += 1; 65 } 66} 67 68void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success) 69{ 70 if (LE_FAILURE(success)) { 71 return; 72 } 73 74 for (le_int32 fixup = 0; fixup < fFixupCount; fixup += 1) { 75 le_int32 baseIndex = fFixupData[fixup].fBaseIndex; 76 le_int32 mpreIndex = fFixupData[fixup].fMPreIndex; 77 le_int32 mpreLimit = mpreIndex + 1; 78 79 while (glyphStorage[baseIndex] == 0xFFFF || glyphStorage[baseIndex] == 0xFFFE) { 80 baseIndex -= 1; 81 } 82 83 while (glyphStorage[mpreLimit] == 0xFFFF || glyphStorage[mpreLimit] == 0xFFFE) { 84 mpreLimit += 1; 85 } 86 87 if (mpreLimit == baseIndex) { 88 continue; 89 } 90 91 LEErrorCode success = LE_NO_ERROR; 92 le_int32 mpreCount = mpreLimit - mpreIndex; 93 le_int32 moveCount = baseIndex - mpreLimit; 94 le_int32 mpreDest = baseIndex - mpreCount; 95 LEGlyphID *mpreSave = LE_NEW_ARRAY(LEGlyphID, mpreCount); 96 le_int32 *indexSave = LE_NEW_ARRAY(le_int32, mpreCount); 97 98 if (mpreSave == NULL || indexSave == NULL) { 99 LE_DELETE_ARRAY(mpreSave); 100 LE_DELETE_ARRAY(indexSave); 101 success = LE_MEMORY_ALLOCATION_ERROR; 102 return; 103 } 104 105 le_int32 i; 106 107 for (i = 0; i < mpreCount; i += 1) { 108 mpreSave[i] = glyphStorage[mpreIndex + i]; 109 indexSave[i] = glyphStorage.getCharIndex(mpreIndex + i, success); //charIndices[mpreIndex + i]; 110 } 111 112 for (i = 0; i < moveCount; i += 1) { 113 LEGlyphID glyph = glyphStorage[mpreLimit + i]; 114 le_int32 charIndex = glyphStorage.getCharIndex(mpreLimit + i, success); 115 116 glyphStorage[mpreIndex + i] = glyph; 117 glyphStorage.setCharIndex(mpreIndex + i, charIndex, success); 118 } 119 120 for (i = 0; i < mpreCount; i += 1) { 121 glyphStorage[mpreDest + i] = mpreSave[i]; 122 glyphStorage.setCharIndex(mpreDest, indexSave[i], success); 123 } 124 125 LE_DELETE_ARRAY(indexSave); 126 LE_DELETE_ARRAY(mpreSave); 127 } 128} 129 130U_NAMESPACE_END 131