1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _SV_GRAPHITELAYOUT_HXX 25 #define _SV_GRAPHITELAYOUT_HXX 26 // Description: An implementation of the SalLayout interface that uses the 27 // Graphite engine. 28 29 // We need this to enable namespace support in libgrengine headers. 30 #define GR_NAMESPACE 31 32 #define GRCACHE 1 33 34 // Standard Library 35 #include <memory> 36 #include <vector> 37 #include <utility> 38 // Libraries 39 #include <preextstl.h> 40 #include <graphite/GrClient.h> 41 #include <graphite/Font.h> 42 #include <graphite/GrConstants.h> 43 #include <graphite/GrAppData.h> 44 #include <graphite/SegmentAux.h> 45 #include <postextstl.h> 46 // Platform 47 #include <sallayout.hxx> 48 #include <vcl/dllapi.h> 49 // Module 50 51 // Module type definitions and forward declarations. 52 // 53 class TextSourceAdaptor; 54 class GraphiteFontAdaptor; 55 class GrSegRecord; 56 // SAL/VCL types 57 class ServerFont; 58 59 #ifdef WNT 60 // The GraphiteWinFont is just a wrapper to enable GrFontHasher to be a friend 61 // so that UniqueCacheInfo can be called. 62 #include <graphite/WinFont.h> 63 class GraphiteWinFont : public gr::WinFont 64 { 65 friend class GrFontHasher; 66 public: GraphiteWinFont(HDC hdc)67 GraphiteWinFont(HDC hdc) : gr::WinFont(hdc) {}; ~GraphiteWinFont()68 virtual ~GraphiteWinFont() {}; 69 }; 70 #endif 71 // Graphite types 72 namespace gr { class Segment; class GlyphIterator; } 73 namespace grutils { class GrFeatureParser; } 74 75 // This class uses the SIL Graphite engine to provide complex text layout services to the VCL 76 // @author tse 77 // 78 class VCL_PLUGIN_PUBLIC GraphiteLayout : public SalLayout 79 { 80 public: 81 // Mask to allow Word break status to be stored within mvChar2BaseGlyph 82 enum { 83 WORD_BREAK_BEFORE = 0x40000000, 84 HYPHEN_BREAK_BEFORE = 0x80000000, 85 BREAK_MASK = 0xC0000000, 86 GLYPH_INDEX_MASK = 0x3FFFFFFF 87 } LineBreakMask; 88 89 class Glyphs : public std::vector<GlyphItem> 90 { 91 public: 92 typedef std::pair<Glyphs::const_iterator, Glyphs::const_iterator> iterator_pair_t; 93 94 void fill_from(gr::Segment & rSeg, ImplLayoutArgs & rArgs, 95 bool bRtl, long &rWidth, float fScaling, 96 std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, 97 std::vector<int> & rCharDxs); 98 void move_glyph(Glyphs::iterator, long dx); 99 100 const_iterator cluster_base(const_iterator) const; 101 iterator_pair_t neighbour_clusters(const_iterator) const; 102 private: 103 std::pair<float,float> appendCluster(gr::Segment & rSeg, ImplLayoutArgs & rArgs, 104 bool bRtl, float fSegmentAdvance, int nFirstCharInCluster, int nNextChar, 105 int nFirstGlyphInCluster, int nNextGlyph, float fScaling, 106 std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, 107 std::vector<int> & rCharDxs, long & rDXOffset); 108 void append(gr::Segment & rSeg, ImplLayoutArgs & rArgs, gr::GlyphInfo & rGi, float nextGlyphOrigin, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs, long & rDXOffset, bool bIsBase); 109 }; 110 111 mutable Glyphs mvGlyphs; 112 void clear(); 113 114 private: 115 TextSourceAdaptor * mpTextSrc; // Text source. 116 gr::LayoutEnvironment maLayout; 117 const gr::Font &mrFont; 118 long mnWidth; 119 std::vector<int> mvCharDxs; 120 std::vector<int> mvChar2BaseGlyph; 121 std::vector<int> mvGlyph2Char; 122 float mfScaling; 123 const grutils::GrFeatureParser * mpFeatures; 124 125 public: 126 explicit GraphiteLayout( const gr::Font& font, const grutils::GrFeatureParser* features = NULL ) throw(); 127 128 // used by upper layers 129 virtual bool LayoutText( ImplLayoutArgs& ); // first step of layout 130 // split into two stages to allow dc to be restored on the segment 131 #ifdef GRCACHE 132 gr::Segment * CreateSegment(ImplLayoutArgs& rArgs, GrSegRecord ** pRecord = NULL); 133 bool LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment, GrSegRecord * pSegRecord); 134 #else 135 gr::Segment * CreateSegment(ImplLayoutArgs& rArgs); 136 bool LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment); 137 #endif 138 139 virtual void AdjustLayout( ImplLayoutArgs& ); // adjusting positions 140 141 // methods using string indexing 142 virtual int GetTextBreak( long nMaxWidth, long nCharExtra=0, int nFactor=1 ) const; 143 virtual long FillDXArray( sal_Int32* pDXArray ) const; 144 virtual void ApplyDXArray(ImplLayoutArgs &rArgs, std::vector<int> & rDeltaWidth); 145 146 virtual void GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray ) const; 147 148 // methods using glyph indexing 149 virtual int GetNextGlyphs(int nLen, sal_GlyphId* pGlyphIdxAry, ::Point & rPos, int&, 150 sal_Int32* pGlyphAdvAry = 0, int* pCharPosAry = 0 ) const; 151 152 // used by glyph+font+script fallback 153 virtual void MoveGlyph( int nStart, long nNewXPos ); 154 virtual void DropGlyph( int nStart ); 155 virtual void Simplify( bool bIsBase ); 156 157 // Dummy implementation so layout can be shared between Linux/Windows DrawText(SalGraphics &) const158 virtual void DrawText(SalGraphics&) const {}; 159 160 virtual ~GraphiteLayout() throw(); SetFeatures(grutils::GrFeatureParser * aFeature)161 void SetFeatures(grutils::GrFeatureParser * aFeature) { mpFeatures = aFeature; } SetFontScale(float s)162 void SetFontScale(float s) { mfScaling = s; }; textSrc() const163 const TextSourceAdaptor * textSrc() const { return mpTextSrc; }; 164 virtual sal_GlyphId getKashidaGlyph(int & width) = 0; 165 void kashidaJustify(std::vector<int> & rDeltaWidth, sal_GlyphId, int width); 166 167 static const int EXTRA_CONTEXT_LENGTH; 168 private: 169 int glyph_to_char(Glyphs::iterator); 170 std::pair<int,int> glyph_to_chars(const GlyphItem &) const; 171 172 std::pair<long,long> caret_positions(size_t) const; 173 void expandOrCondense(ImplLayoutArgs &rArgs); 174 }; 175 176 #endif // _SV_GRAPHITELAYOUT_HXX 177