1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 /* AbiWord
3  * Copyright (C) 2004 Tomas Frydrych
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301 USA.
19  */
20 
21 #ifndef GR_RENDERINFO_H
22 #define GR_RENDERINFO_H
23 
24 #include "ut_types.h"
25 #include "ut_vector.h"
26 #include "gr_Graphics.h"
27 
28 class UT_TextIterator;
29 
30 /**
31    Identifies scripts for the shaping engine; the actual values are
32    shaper specific and of no consequence to the xp layer; the only
33    values that are defined are:
34 
35    Undefined - identifies text that requires no special processing.
36    Void      - indicates the record does not represent real item;
37    only used with the last (dummy) record in GR_Itemization
38 */
39 enum GR_ScriptType
40 {
41 	GRScriptType_Undefined = 0,
42 	GRScriptType_Void = 0xffffffff
43 };
44 
45 /** used to identify GR_RenderInfo and related classes
46 	add as required */
47 enum GRRI_Type
48 {
49 	GRRI_XP = 0,
50 	GRRI_WIN32,
51 	GRRI_UNIX,
52 	GRRI_COCOA,
53 	GRRI_WIN32_UNISCRIBE,
54 	GRRI_CAIRO_PANGO,
55 
56 	GRRI_BUILT_IN_LAST = 0x0000ffff,
57 
58 	GRRI_UNKNOWN = 0xffffffff
59 };
60 
61 
62 /**
63    This is an abstract class that describes an item of text and is passed
64    to the shaper. Each platform needs to implement a derived class that
65    would hold item information required by the specific shaper.
66 
67    \note constructor should be protected; new instances can only be created via
68    GR_Graphics::newItem()
69 */
70 class ABI_EXPORT GR_Item
71 {
72   public:
~GR_Item()73 	virtual ~GR_Item(){};
74 	virtual GR_ScriptType getType() const = 0;
75 	virtual GR_Item * makeCopy() const = 0; // make a copy of this item
76 	virtual GRRI_Type getClassId() const = 0;
77 
78   protected:
GR_Item()79 	GR_Item(){};
80 };
81 
82 
83 class ABI_EXPORT GR_XPItem : public GR_Item
84 {
85 	friend class GR_Graphics;
86 
87   public:
~GR_XPItem()88 	virtual ~GR_XPItem(){};
89 
getType()90 	virtual GR_ScriptType getType() const {return m_eType;}
makeCopy()91 	virtual GR_Item * makeCopy() const {return new GR_XPItem(m_eType);}
getClassId()92 	virtual GRRI_Type getClassId() const {return GRRI_XP;}
93 
94   protected:
GR_XPItem()95 	GR_XPItem():
96 	   m_eType(GRScriptType_Undefined){};
GR_XPItem(GR_ScriptType t)97 	GR_XPItem(GR_ScriptType t):
98 	   m_eType(t){};
99 
100 	GR_ScriptType m_eType;
101 };
102 
103 
104 /**
105    describes itemization of text
106 
107    offset is where an item starts
108    type   is GR_ScriptType for the item
109 
110    length of item is calculated as difference of offsets between
111    neighbouring items
112 
113    there is always to be one dummy item of type GRScriptType_Void
114    after the last item with offset set so as to alow to calculate
115    length of the last valid item
116 
117    getItemCount() returns the count of all items, including the dummy
118    GRScriptType_Void item.
119 */
120 class ABI_EXPORT GR_Itemization
121 {
122   public:
GR_Itemization()123 	GR_Itemization():
124 	    m_iEmbedingLevel(0),
125 		m_iDirOverride(0),
126 		m_bShowControlChars(false),
127 	    m_pLang(NULL),
128 	    m_pFont(NULL)
129 	{};
130 
~GR_Itemization()131 	virtual ~GR_Itemization() {clear();} // do not delete the actual
132 										 // items, they get passed on
133 										 // to the runs
134 
getItemCount()135 	UT_sint32       getItemCount() const {return m_vOffsets.getItemCount();}
getNthOffset(UT_sint32 i)136 	UT_sint32       getNthOffset(UT_sint32 i) const {return m_vOffsets.getNthItem(i);}
getNthType(UT_sint32 i)137 	GR_ScriptType   getNthType(UT_sint32 i) const
138 	                   {return ((GR_Item*)m_vItems.getNthItem(i))->getType();}
139 
getNthLength(UT_sint32 i)140 	UT_uint32       getNthLength(UT_sint32 i)
141 	                   {
142 						  UT_return_val_if_fail(i < m_vOffsets.getItemCount()-1, 0);
143 						  return m_vOffsets.getNthItem(i+1) - m_vOffsets.getNthItem(i);
144 					   }
145 
getNthItem(UT_sint32 i)146 	GR_Item *       getNthItem(UT_sint32 i) const {return (GR_Item *)m_vItems.getNthItem(i);}
147 
addItem(UT_sint32 offset,const GR_Item * item)148 	void            addItem(UT_sint32 offset, const GR_Item *item)
149 	                    { m_vOffsets.addItem(offset); m_vItems.addItem(item);}
150 
insertItem(UT_sint32 indx,UT_sint32 offset,const GR_Item * item)151 	void            insertItem(UT_sint32 indx, UT_sint32 offset, const GR_Item *item)
152 	                    { m_vOffsets.insertItemAt(offset, indx); m_vItems.insertItemAt(item,indx);}
153 
154 	void            clear();
155 
setEmbedingLevel(UT_uint32 l)156 	void            setEmbedingLevel(UT_uint32 l) {m_iEmbedingLevel = l;}
getEmbedingLevel()157 	UT_uint32       getEmbedingLevel() const {return m_iEmbedingLevel;}
158 
setDirOverride(UT_BidiCharType o)159 	void            setDirOverride(UT_BidiCharType o) {m_iDirOverride = o;}
getDirOverride()160 	UT_BidiCharType getDirOverride() const {return m_iDirOverride;}
161 
setShowControlChars(bool s)162 	void            setShowControlChars(bool s) {m_bShowControlChars = s;}
getShowControlChars()163 	bool            getShowControlChars() const {return m_bShowControlChars;}
164 
setLang(const char * l)165 	void            setLang(const char * l) {m_pLang = l;}
getLang()166 	const char *    getLang()const {return m_pLang;}
167 
setFont(const GR_Font * pFont)168 	void            setFont(const GR_Font * pFont) {m_pFont = pFont;}
getFont()169 	const GR_Font * getFont()const {return m_pFont;}
170 
171   private:
172 	UT_NumberVector m_vOffsets;
173 	UT_Vector       m_vItems;
174 
175 	UT_uint32       m_iEmbedingLevel;
176 	UT_BidiCharType m_iDirOverride;
177 	bool            m_bShowControlChars;
178 	const char *    m_pLang;
179 	const GR_Font * m_pFont;
180 };
181 
182 /**
183    encapsulates output of GR_Graphics::shape() which is passed as
184    input to GR_Graphics::renderChars().
185 
186    This is abstract class and suitable functionality is to be provided
187    by platform code.
188 
189    <b>Notes on append(), split() and cut()</b>
190 
191    These functions allow our fp_TextRun to merge with next or to split
192    into two without having to know about various platform dependent
193    chaches that speed up shaping and drawing; append()
194    joins all such chaches, while split() splits them into two. Before
195    spliting, split() must allocate appropriate GR_FERenderInfo into pri.
196 
197    cut() attempts to remove a section of length iLen starting at
198    offset without re-shaping the whole buffer; if it succeeds it
199    returns true; if it fails and the chaches need to be re-calculated
200    it return false (it should not carry out the reshaping per se)
201 
202    m_iOffset and m_iLength contain offset and length pertinent to the
203    current operation and their state is undefined: the user should
204    always set them if the function to which GR_RenderInfo is passed is
205    going to use them
206 */
207 class ABI_EXPORT GR_RenderInfo
208 {
209   public:
GR_RenderInfo(GR_ScriptType type)210 	GR_RenderInfo(GR_ScriptType type)
211 		: m_iOffset(0), m_iLength(0), m_eShapingResult(GRSR_Unknown),
212  		  m_eState(GRSR_Unknown), m_eScriptType(type),
213 		  m_pText(NULL), m_iVisDir(UT_BIDI_LTR),
214 	      m_xoff(0), m_yoff(),
215 	      m_pGraphics(NULL), m_pFont(NULL),
216 		  m_iJustificationPoints(0),
217 		  m_iJustificationAmount(0),
218 		  m_bLastOnLine(false),
219 		  m_pItem(NULL),
220 		  m_bInvalidateFontCache(false){};
221 
222 
~GR_RenderInfo()223 	virtual ~GR_RenderInfo(){};
224 
225 	virtual GRRI_Type getType() const = 0;
226 
227 	virtual bool append(GR_RenderInfo &ri, bool bReverse = false) = 0;
228 	virtual bool split (GR_RenderInfo *&pri, bool bReverse = false) = 0;
229 	virtual bool cut(UT_uint32 offset, UT_uint32 len, bool bReverse = false) = 0;
230 
canAppend(GR_RenderInfo & ri)231 	virtual bool canAppend(GR_RenderInfo &ri) const
232 	              {return (m_eScriptType == ri.m_eScriptType);}
233 
234 	virtual bool isJustified() const = 0;
235 
236 
237 	UT_sint32           m_iOffset;
238 	UT_sint32           m_iLength;
239 	GRShapingResult     m_eShapingResult;
240 	GRShapingResult     m_eState;
241 	GR_ScriptType       m_eScriptType;
242 	UT_TextIterator *   m_pText;
243 	UT_BidiCharType     m_iVisDir;
244 	UT_sint32           m_xoff;
245 	UT_sint32           m_yoff;
246 
247 	const GR_Graphics * m_pGraphics;
248 	const GR_Font     * m_pFont;
249 
250 	UT_sint32           m_iJustificationPoints;
251 	UT_sint32           m_iJustificationAmount;
252 	bool                m_bLastOnLine;
253 	const GR_Item *     m_pItem;
254 	bool                m_bInvalidateFontCache;
255 
256  private:
257 	/** never to be implemented (constructor always has to set
258 		m_eScriptType to actual value)*/
GR_RenderInfo()259 	GR_RenderInfo() {};
260 };
261 
262 /**
263    This is an xp implementation of GR_RenderInfo for use with the
264    built in UT_contextGlyph class.
265 */
266 class ABI_EXPORT GR_XPRenderInfo : public GR_RenderInfo
267 {
268   public:
269 	GR_XPRenderInfo(GR_ScriptType type);
270 
271 	virtual ~GR_XPRenderInfo();
272 
getType()273 	virtual GRRI_Type getType() const {return GRRI_XP;}
274 
275 	virtual bool append(GR_RenderInfo &ri, bool bReverse = false);
276 	virtual bool split (GR_RenderInfo *&pri, bool bReverse = false);
277 	virtual bool cut(UT_uint32 offset, UT_uint32 len, bool bReverse = false);
278 
isJustified()279 	virtual bool isJustified() const {return (m_iJustificationPoints != 0);}
280 
281 	void prepareToRenderChars();
282 
283 
284 	UT_UCS4Char *       m_pChars;
285 	UT_sint32 *         m_pWidths;
286 	UT_sint32           m_iBufferSize;
287 	UT_sint32 *         m_pSegmentOffset;
288 	UT_sint32           m_iSegmentCount;
289 	UT_sint32           m_iSpaceWidthBeforeJustification; // <0 for not justified
290 	UT_uint32           m_iTotalLength;
291 
292 	// these can be static as for now we do not want to chache anything
293 	static UT_sint32	    s_iClassInstanceCount;
294 	static UT_UCS4Char *    s_pCharBuff;
295 	static UT_sint32 *      s_pWidthBuff;
296 	static UT_sint32        s_iBuffSize;
297 	static UT_sint32 *      s_pAdvances;
298 	static GR_RenderInfo *  s_pOwner;
299   private:
300 	void                   _constructorCommonCode();
301 	inline void            _stripLigaturePlaceHolders();
302 	inline void            _calculateCharAdvances();
303 	inline bool            _checkAndFixStaticBuffers();
304 
305 };
306 
307 
308 /**
309    Encapsulates input to GR_Graphics::shape()
310 */
311 class ABI_EXPORT GR_ShapingInfo
312 {
313   public:
314 	enum TextTransform {
315 		NONE = 0,
316 		CAPITALIZE,
317 		UPPERCASE,
318 		LOWERCASE
319 	};
320 
321 	GR_ShapingInfo(UT_TextIterator & text, UT_uint32 iLen,
322 				   const char * pLang,
323 				   UT_BidiCharType iVisDir,
324 				   GRShapingResult eShapingRequired,
325 				   const GR_Font * pFont,
326 				   const GR_Item * pItem,
327 				   TextTransform textTransform = NONE,
328 				   bool previousWasSpace = false)
m_Text(text)329 		:m_Text(text), m_iLength(iLen), m_pLang(pLang), m_iVisDir(iVisDir),
330 		 m_eShapingRequired(eShapingRequired),
331 	     m_pFont(pFont),
332 		m_iJustifyBy(0),
333 		m_pItem(pItem),
334 		m_TextTransform(textTransform),
335 		m_previousWasSpace(previousWasSpace)
336 	{
337 	}
338 
~GR_ShapingInfo()339 	virtual ~GR_ShapingInfo() {};
340 
341 	UT_TextIterator &   m_Text;
342 	UT_sint32           m_iLength;
343 	const char *        m_pLang;
344 	UT_BidiCharType     m_iVisDir;
345 	GRShapingResult     m_eShapingRequired;
346 
347 	const GR_Font *     m_pFont;
348 
349 	UT_uint32           m_iJustifyBy;
350 
351 	const GR_Item *     m_pItem;
352 
353 	TextTransform       m_TextTransform;
354 	bool                m_previousWasSpace;
355 };
356 
357 
358 #endif /* GR_RENDERINFO_H */
359