Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp
38918 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/242526/*27*28* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved29*30*/3132#include "LETypes.h"33#include "LEScripts.h"34#include "LEGlyphFilter.h"35#include "LEGlyphStorage.h"36#include "LayoutEngine.h"37#include "OpenTypeLayoutEngine.h"38#include "ArabicLayoutEngine.h"39#include "ScriptAndLanguageTags.h"40#include "CharSubstitutionFilter.h"4142#include "GlyphSubstitutionTables.h"43#include "GlyphDefinitionTables.h"44#include "GlyphPositioningTables.h"4546#include "GDEFMarkFilter.h"4748#include "ArabicShaping.h"49#include "CanonShaping.h"5051U_NAMESPACE_BEGIN5253le_bool CharSubstitutionFilter::accept(LEGlyphID glyph, LEErrorCode &/*success*/) const54{55return fFontInstance->canDisplay((LEUnicode) glyph);56}5758UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)5960ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,61le_int32 languageCode, le_int32 typoFlags,62const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,63LEErrorCode &success)64: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)65{66fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);67fFeatureOrder = TRUE;68}6970ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,71le_int32 languageCode,72le_int32 typoFlags, LEErrorCode &success)73: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)74{75fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);7677// NOTE: We don't need to set fFeatureOrder to TRUE here78// because this constructor is only called by the constructor79// for UnicodeArabicOpenTypeLayoutEngine, which uses a pre-built80// GSUB table that has the features in the correct order.8182//fFeatureOrder = TRUE;83}8485ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()86{87// nothing to do88}8990// Input: characters91// Output: characters, char indices, tags92// Returns: output character count93le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,94le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,95LEGlyphStorage &glyphStorage, LEErrorCode &success)96{97if (LE_FAILURE(success)) {98return 0;99}100101if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {102success = LE_ILLEGAL_ARGUMENT_ERROR;103return 0;104}105106outChars = LE_NEW_ARRAY(LEUnicode, count);107108if (outChars == NULL) {109success = LE_MEMORY_ALLOCATION_ERROR;110return 0;111}112113glyphStorage.allocateGlyphArray(count, rightToLeft, success);114glyphStorage.allocateAuxData(success);115116if (LE_FAILURE(success)) {117LE_DELETE_ARRAY(outChars);118return 0;119}120121CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage);122123// Note: This processes the *original* character array so we can get context124// for the first and last characters. This is OK because only the marks125// will have been reordered, and they don't contribute to shaping.126ArabicShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage);127128return count;129}130131void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,132LEGlyphStorage &glyphStorage, LEErrorCode &success)133{134if (LE_FAILURE(success)) {135return;136}137138if (chars == NULL || offset < 0 || count < 0) {139success = LE_ILLEGAL_ARGUMENT_ERROR;140return;141}142143if (!fGPOSTable.isEmpty()) {144OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);145} else if (!fGDEFTable.isEmpty()) {146GDEFMarkFilter filter(fGDEFTable, success);147adjustMarkGlyphs(glyphStorage, &filter, success);148} else {149LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData,150CanonShaping::glyphDefinitionTable,151CanonShaping::glyphDefinitionTableLen);152GDEFMarkFilter filter(gdefTable, success);153154adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);155}156}157158UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)159: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)160{161fGSUBTable.setTo(LETableReference::kStaticData, (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable, CanonShaping::glyphSubstitutionTableLen);162fGDEFTable.setTo(LETableReference::kStaticData, (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);163/* OpenTypeLayoutEngine will allocate a substitution filter */164}165166UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()167{168/* OpenTypeLayoutEngine will cleanup the substitution filter */169}170171// "glyphs", "indices" -> glyphs, indices172le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success)173{174if (LE_FAILURE(success)) {175return 0;176}177178// FIXME: we could avoid the memory allocation and copy if we179// made a clone of mapCharsToGlyphs which took the fake glyphs180// directly.181le_int32 tempGlyphCount = tempGlyphStorage.getGlyphCount();182LEUnicode *tempChars = LE_NEW_ARRAY(LEUnicode, tempGlyphCount);183184if (tempChars == NULL) {185success = LE_MEMORY_ALLOCATION_ERROR;186return 0;187}188189for (le_int32 i = 0; i < tempGlyphCount; i += 1) {190tempChars[i] = (LEUnicode) LE_GET_GLYPH(tempGlyphStorage[i]);191}192193glyphStorage.adoptCharIndicesArray(tempGlyphStorage);194195ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphStorage, success);196197LE_DELETE_ARRAY(tempChars);198199return tempGlyphCount;200}201202void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)203{204if (LE_FAILURE(success)) {205return;206}207208if (chars == NULL || offset < 0 || count < 0) {209success = LE_ILLEGAL_ARGUMENT_ERROR;210return;211}212213le_int32 i, dir = 1, out = 0;214215if (reverse) {216out = count - 1;217dir = -1;218}219220glyphStorage.allocateGlyphArray(count, reverse, success);221222for (i = 0; i < count; i += 1, out += dir) {223glyphStorage[out] = (LEGlyphID) chars[offset + i];224}225}226227void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,228LEGlyphStorage &glyphStorage, LEErrorCode &success)229{230if (LE_FAILURE(success)) {231return;232}233234if (chars == NULL || offset < 0 || count < 0) {235success = LE_ILLEGAL_ARGUMENT_ERROR;236return;237}238239GDEFMarkFilter filter(fGDEFTable, success);240241adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);242}243244U_NAMESPACE_END245246247248