|  | /************************************************************** | 
|  | * | 
|  | * Licensed to the Apache Software Foundation (ASF) under one | 
|  | * or more contributor license agreements.  See the NOTICE file | 
|  | * distributed with this work for additional information | 
|  | * regarding copyright ownership.  The ASF licenses this file | 
|  | * to you under the Apache License, Version 2.0 (the | 
|  | * "License"); you may not use this file except in compliance | 
|  | * with the License.  You may obtain a copy of the License at | 
|  | * | 
|  | *   http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, | 
|  | * software distributed under the License is distributed on an | 
|  | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | * KIND, either express or implied.  See the License for the | 
|  | * specific language governing permissions and limitations | 
|  | * under the License. | 
|  | * | 
|  | *************************************************************/ | 
|  |  | 
|  |  | 
|  |  | 
|  | // MARKER(update_precomp.py): autogen include statement, do not remove | 
|  | #include "precompiled_vcl.hxx" | 
|  |  | 
|  | // We need this to enable namespace support in libgrengine headers. | 
|  | #define GR_NAMESPACE | 
|  |  | 
|  | // Header files | 
|  | // | 
|  | // Standard Library | 
|  | #include <string> | 
|  | #include <cassert> | 
|  | #include "graphite_textsrc.hxx" | 
|  | #include <graphite_features.hxx> | 
|  |  | 
|  | // class TextSourceAdaptor implementation. | 
|  | // | 
|  | TextSourceAdaptor::~TextSourceAdaptor() | 
|  | { | 
|  | delete mpFeatures; | 
|  | } | 
|  |  | 
|  | gr::UtfType TextSourceAdaptor::utfEncodingForm() { | 
|  | return gr::kutf16; | 
|  | } | 
|  |  | 
|  |  | 
|  | size_t TextSourceAdaptor::getLength() | 
|  | { | 
|  | return maLayoutArgs.mnLength; | 
|  | } | 
|  |  | 
|  |  | 
|  | size_t  TextSourceAdaptor::fetch(gr::toffset, size_t, gr::utf32 *) | 
|  | { | 
|  | assert(false); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | size_t  TextSourceAdaptor::fetch(gr::toffset offset, size_t char_count, gr::utf16 * char_buffer) | 
|  | { | 
|  | assert(char_buffer); | 
|  |  | 
|  | size_t copy_count =  std::min(size_t(maLayoutArgs.mnLength), char_count); | 
|  | std::copy(maLayoutArgs.mpStr + offset, maLayoutArgs.mpStr + offset + copy_count, char_buffer); | 
|  |  | 
|  | return copy_count; | 
|  | } | 
|  |  | 
|  |  | 
|  | size_t TextSourceAdaptor::fetch(gr::toffset, size_t, gr::utf8  *) | 
|  | { | 
|  | assert(false); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | inline void TextSourceAdaptor::getCharProperties(const int nCharIdx, int & min, int & lim, size_t & depth) | 
|  | { | 
|  | maLayoutArgs.ResetPos(); | 
|  | bool rtl = maLayoutArgs.mnFlags & SAL_LAYOUT_BIDI_RTL; | 
|  | for(depth = ((rtl)? 1:0); maLayoutArgs.maRuns.GetRun(&min, &lim, &rtl); maLayoutArgs.maRuns.NextRun()) | 
|  | { | 
|  | if (min > nCharIdx) | 
|  | break; | 
|  | // Only increase the depth when a change of direction occurs. | 
|  | depth += int(rtl ^ bool(depth & 0x1)); | 
|  | if (min <= nCharIdx && nCharIdx < lim) | 
|  | break; | 
|  | } | 
|  | // If there is no run for this position increment the depth, but don't | 
|  | // change if this is out of bounds context | 
|  | if (lim > 0 && nCharIdx >= lim && nCharIdx < maLayoutArgs.mnEndCharPos) | 
|  | depth++; | 
|  | } | 
|  |  | 
|  |  | 
|  | bool TextSourceAdaptor::getRightToLeft(gr::toffset nCharIdx) | 
|  | { | 
|  | size_t depth; | 
|  | int min, lim = 0; | 
|  | getCharProperties(nCharIdx, min, lim, depth); | 
|  | //printf("getRtl %d,%x=%d\n", nCharIdx, maLayoutArgs.mpStr[nCharIdx], depth & 0x1); | 
|  | return depth & 0x1; | 
|  | } | 
|  |  | 
|  |  | 
|  | unsigned int TextSourceAdaptor::getDirectionDepth(gr::toffset nCharIdx) | 
|  | { | 
|  | size_t depth; | 
|  | int min, lim; | 
|  | getCharProperties(nCharIdx, min, lim, depth); | 
|  | //printf("getDirectionDepth %d,%x=%d\n", nCharIdx, maLayoutArgs.mpStr[nCharIdx], depth); | 
|  | return depth; | 
|  | } | 
|  |  | 
|  |  | 
|  | float TextSourceAdaptor::getVerticalOffset(gr::toffset) | 
|  | { | 
|  | return 0.0f;    //TODO: Implement correctly | 
|  | } | 
|  |  | 
|  | gr::isocode TextSourceAdaptor::getLanguage(gr::toffset) | 
|  | { | 
|  | if (mpFeatures && mpFeatures->hasLanguage()) | 
|  | return mpFeatures->getLanguage(); | 
|  | gr::isocode unknown = {{0,0,0,0}}; | 
|  | return unknown; | 
|  | } | 
|  |  | 
|  | ext_std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx) | 
|  | { | 
|  |  | 
|  | if (nCharIdx < unsigned(maLayoutArgs.mnMinCharPos)) | 
|  | return ext_std::make_pair(0, maLayoutArgs.mnMinCharPos); | 
|  |  | 
|  | if (nCharIdx < mnEnd) | 
|  | return ext_std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd); | 
|  |  | 
|  | return ext_std::make_pair(mnEnd, maLayoutArgs.mnLength); | 
|  | } | 
|  |  | 
|  | size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * settings) | 
|  | { | 
|  | if (mpFeatures) return mpFeatures->getFontFeatures(settings); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | bool TextSourceAdaptor::sameSegment(gr::toffset char_idx1, gr::toffset char_idx2) | 
|  | { | 
|  | const ext_std::pair<gr::toffset, gr::toffset> | 
|  | range1 = propertyRange(char_idx1), | 
|  | range2 = propertyRange(char_idx2); | 
|  |  | 
|  | return range1 == range2; | 
|  | } | 
|  |  | 
|  | void TextSourceAdaptor::setFeatures(const grutils::GrFeatureParser * pFeatures) | 
|  | { | 
|  | mpFeatures = new grutils::GrFeatureParser(*pFeatures); | 
|  | } |