1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 /* AbiWord
3  * Copyright (C) 1998 AbiSource, Inc.
4  * Copyright (C) 2002 Tomas Frydrych, <tomas@frydrych.uklinux.net>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301 USA.
20  */
21 
22 #ifndef GR_GRAPHICS_H
23 #define GR_GRAPHICS_H
24 
25 #include <memory>
26 
27 #include "xap_Features.h"
28 
29 #include "ut_types.h"
30 #include "ut_units.h"
31 #include "ut_growbuf.h"
32 #include "ut_misc.h"
33 #include "gr_Image.h"
34 #include "gr_Caret.h"
35 #include "gr_Transform.h"
36 #include "gr_CharWidthsCache.h"
37 #include "ut_vector.h"
38 #include "ut_stack.h"
39 #include "ut_TextIterator.h"
40 
41 #ifdef ABI_GRAPHICS_PLUGIN
42 #define VIRTUAL_SFX = 0
43 #else
44 #define VIRTUAL_SFX
45 #endif
46 
47 class UT_RGBColor;
48 class XAP_PrefsScheme;
49 class XAP_Frame;
50 class UT_String;
51 class GR_RenderInfo;
52 class GR_Itemization;
53 class GR_ShapingInfo;
54 
55 
56 /*!
57   GR_Font is a reference to a font.  As it happens, everything about fonts
58   is platform-specific, so the class contains nothing.  All of its behavior
59   and functionality is contained within its subclasses, each of which provides
60   the implementation for some specific font technology.
61 
62   May 16 2003
63   The assertion made above is mostly wrong. Font works almost the same
64   on every platform. We have metrics, glyphs, measurement, etc. Sure implementation is utterly
65   platform dependent, but we can provide a mostly XP interface to that.
66   That would certainly reduce platform code a increase XP code.
67    -- Hub
68 */
69 
70 class GR_Graphics;
71 class GR_Painter;
72 class GR_Caret;
73 
74 typedef enum {
75 	GR_FONT_UNSET=0,
76 	GR_FONT_UNIX,
77 	GR_FONT_UNIX_PANGO,
78 	GR_FONT_WIN32,
79 	GR_FONT_WIN32_USP
80 } GrFontType;
81 
82 class ABI_EXPORT GR_Font
83 {
84 	friend class GR_Graphics;
85 	friend class std::map<std::string, GR_Font*>;
86 
87  public:
88 	// want the destructor public so that the derrived graphics classes can delete font
89 	// objects without having to be declared here as friends
90  	virtual ~GR_Font();
91 
92 
93 	typedef enum { FF_Unknown = 0, FF_Roman, FF_Swiss, FF_Modern,
94 				   FF_Script, FF_Decorative, FF_Technical, FF_BiDi, FF_Last } FontFamilyEnum;
95 	typedef enum { FP_Unknown = 0, FP_Fixed, FP_Variable } FontPitchEnum;
96 
97 	// The following is actually implemented in platform code.
98 	// It is primarily used to characterize fonts for RTF export.
99 	static void s_getGenericFontProperties(const char * szFontName,
100 										   FontFamilyEnum * pff,
101 										   FontPitchEnum * pfp,
102 										   bool * pbTrueType);
103 
getFamily()104 	virtual const char* getFamily() const { return NULL; }
getAllocNumber()105 	UT_uint32           getAllocNumber() const {return m_iAllocNo;}
106 	/*!
107 		Measure the unremapped char to be put into the cache.
108 		That means measuring it for a font size of 120
109 	 */
110 	virtual UT_sint32 measureUnremappedCharForCache(UT_UCSChar cChar) const = 0;
111 	virtual const std::string & hashKey(void) const;
112 	UT_sint32 getCharWidthFromCache (UT_UCSChar c) const;
113 
114 	/*reimplement if you want to instanciate something else */
115 	virtual GR_CharWidths* newFontWidths(void) const;
116 	/*
117 	   implemented using character widths; platforms might want to
118 	   provide different implementation
119 	   NB: it is essential that this function is fast
120 	*/
121 	virtual bool doesGlyphExist(UT_UCS4Char g) const;
122 //
123 // UT_Rect of glyph in Logical units.
124 // rec.left = bearing Left (distance from origin to start)
125 // rec.width = width of the glyph
126 // rec.top = distance from the origin to the top of the glyph
127 // rec.height = total height of the glyph
128 
129 	virtual bool glyphBox(UT_UCS4Char g, UT_Rect & rec, GR_Graphics * pG) = 0;
s_doesGlyphExist(UT_UCS4Char g,void * instance)130 	static  bool s_doesGlyphExist(UT_UCS4Char g, void *instance)
131 	{
132 		UT_return_val_if_fail(instance, false);
133 		GR_Font * pThis = static_cast<GR_Font*>(instance);
134 		return pThis->doesGlyphExist(g);
135 	}
136 
getType()137 	GrFontType getType()const {return m_eType;}
138 
139   protected:
140 
141 	GR_Font();
142 
_getCharWidths()143 	GR_CharWidths * _getCharWidths() const {return m_pCharWidths;}
144 	/*!
145 	  hash key for font cache. Must be initialized in ctor
146 	 otherwise override hashKey() method
147 	*/
148 	mutable std::string		m_hashKey;
149 
150 	GrFontType               m_eType;
151 
152 private:
153 
154 	static UT_uint32 s_iAllocCount;
155 	UT_uint32        m_iAllocNo;
156 	mutable GR_CharWidths*	m_pCharWidths;
157 };
158 
159 
160 /*
161     GR_GraphicsId defines IDs returned by GR_Graphics::getClassId()
162     used to identify the class in communication with GR_GraphicsFactory.
163 
164     There are three types of IDs: default, built-in and plugin.
165 
166     Default IDs are not assigned permanently to any class and are used
167 	by the factory to allocate default graphics. These IDs are
168 	reallocable -- if the factory receives a request to register a
169 	class under one of these IDs, it will automatically unregister any
170 	class currently registered under that ID.
171 
172 	Built-in IDs are permanently assinged to specific derrived
173 	classes. The factory will refuse to register a class under one of
174 	these IDs if another class is already registered with it.
175 
176 	Plugin IDs are dynamically generated for a graphics class by the
177 	factory. The main draw-back of plugin IDs is that they cannot be
178 	stored in preference profiles. A plugin desinger might prefer to
179 	request a fixed ID from the built-in range (we could use UUIDs to
180 	identify graphics, but that seems an overkill).
181  */
182 enum GR_GraphicsId
183 {
184 	/* default id's */
185 	/* these id's can be reregistered at will */
186 	GRID_DEFAULT         =  0x0,
187 	GRID_DEFAULT_PRINT   =  0x1,
188 
189 	GRID_LAST_DEFAULT    =  0xff,
190 
191 	/* IDs for built-in classes: DO NOT CHANGE THE ASSIGNED VALUES !!!*/
192 	/* (these classes cannot be unregistered) */
193 	GRID_COCOA           =  0x102,
194 	GRID_WIN32           =  0x104,
195 	GRID_UNIX            =  0x105,
196 	GRID_UNIX_PS         =  0x106,
197 	GRID_CAIRO_NULL      =  0x107,
198 
199 	/*add new built-in ids here*/
200 
201 	GRID_LAST_BUILT_IN = 0x200,
202 
203 	/* IDs for extension classes (can be both built-in and plugins) */
204 	/* (these classes can be unregistered by explicit call to
205 	   unregisterClass()) */
206 	GRID_UNIX_PANGO      =  0x201,
207 	GRID_WIN32_UNISCRIBE =  0x202,
208 	GRID_UNIX_PANGO_PRINT = 0x203,
209 	GRID_UNIX_PANGO_PIXMAP = 0x204,
210         GRID_COCOA_PANGO     = 0x205,
211 
212 	GRID_LAST_EXTENSION = 0x0000ffff,
213 
214 	/* id's for plugins will be auto-generatoed from between here */
215 
216 	GRID_UNKNOWN = 0xffffffff
217 };
218 
219 // or-able graphics type
220 enum GR_Capability
221 {
222 	GRCAP_UNKNOWN            = 0,
223 	GRCAP_SCREEN_ONLY        = 1,
224 	GRCAP_PRINTER_ONLY       = 2,
225 	GRCAP_SCREEN_AND_PRINTER = 3
226 };
227 
228 /*!
229     The following class serves as an argument to GR_GraphicsFactory::newGraphics()
230 
231     There should be only one derived class for each platform (not each
232     graphics), capable of holding information for all different
233     graphics classes on the platform.
234 
235     For example, on Unix we have three different classes with the
236     following constructors:
237 
238    	    GR_UnixGraphics(GdkWindow * win, XAP_UnixFontManager * fontManager, XAP_App *app)
239 
240 		PS_Graphics(const char * szFilename,
241 		            const char * szTitle,
242 					const char * szSoftwareNameAndVersion,
243 					XAP_UnixFontManager * fontManager,
244 					bool		 bIsFile,
245 					XAP_App *pApp);
246 
247 		UnixNull_Graphics(XAP_UnixFontManager * fontManager,XAP_App *pApp);
248 
249 	GR_UnixAllocInfo will need to be able to hold parameters for all
250 	the constructors, something like
251 
252 	    class GR_UnixAllocInfo
253 	    {
254 	        GdkWindow *           win;
255 	        XAP_UnixFontManager * fontManager;
256 	        XAP_App *             app;
257 			const char *          szFilename;
258 		    const char *          szTitle;
259 			const char *          szSoftwareNameAndVersion;
260 			bool		          bIsFile;
261 	    };
262 
263 	This does impose some limitations on classes implemented as
264 	plugins: if the plugin class needs something that is not in the
265 	platform class and cannot obtain it by other means (for example by
266 	quering XAP_App), the AllocInfo class will need to be extended.
267 
268 	Platform implementation needs to override getType() so that
269 	graphicsAllocator() can do type-checking.
270 */
271 class ABI_EXPORT GR_AllocInfo
272 {
273   public:
~GR_AllocInfo()274 	virtual ~GR_AllocInfo() {}
275 
getType()276 	virtual GR_GraphicsId getType() const {UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); return GRID_UNKNOWN;}
isPrinterGraphics()277 	virtual bool isPrinterGraphics()const {UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); return false;}
278 };
279 
280 typedef GR_Graphics * (*GR_Allocator)(GR_AllocInfo&);
281 typedef const char *  (*GR_Descriptor)(void);
282 /*
283    The purpose of GR_GraphicsFactory is to allow us to have parallel
284    graphics implementations. For example, on win32 we could have a
285    graphics class using Uniscribe, graphics class without shaping
286    support and graphics class using SIL Graphite. The user then could
287    specify through preferences which shaping engine s/he wishes to
288    use. The factory provides access to all graphics classes known to
289    the application.
290 */
291 class ABI_EXPORT GR_GraphicsFactory
292 {
293 
294   public:
GR_GraphicsFactory()295 	GR_GraphicsFactory(){};
~GR_GraphicsFactory()296 	virtual ~GR_GraphicsFactory(){};
297 
getClassCount()298 	UT_uint32     getClassCount() const {return m_vClassIds.getItemCount();}
299 
300 	bool          registerClass(GR_Allocator, GR_Descriptor, UT_uint32 iClassId);
301 	UT_uint32     registerPluginClass(GR_Allocator, GR_Descriptor);
302 
registerAsDefault(UT_uint32 iClassId,bool bScreen)303 	void          registerAsDefault(UT_uint32 iClassId, bool bScreen)
304 	                     {
305 							 if(bScreen)
306 								 m_iDefaultScreen = iClassId;
307 							 else
308 								 m_iDefaultPrinter = iClassId;
309 						 }
310 
getDefaultClass(bool bScreen)311 	UT_uint32     getDefaultClass(bool bScreen) const {if(bScreen) return m_iDefaultScreen; else return m_iDefaultPrinter;}
312 	bool          unregisterClass(UT_uint32 iClassId);
313 	bool          isRegistered(UT_uint32 iClassId) const;
314 
315 	GR_Graphics * newGraphics(UT_uint32 iClassId, GR_AllocInfo &param) const;
316 	const char *  getClassDescription(UT_uint32 iClassId) const;
317 
318 
319   private:
320 	UT_GenericVector<GR_Allocator>       m_vAllocators;
321 	UT_GenericVector<GR_Descriptor>       m_vDescriptors;
322 	UT_NumberVector m_vClassIds;
323 
324 	UT_uint32       m_iDefaultScreen;
325 	UT_uint32       m_iDefaultPrinter;
326 };
327 
328 
329 enum GRShapingResult
330 {
331 	GRSR_BufferClean = 0x00,                  // clear all bits; see notes above !!!
332 	GRSR_None = 0x01,                         // bit 0 set
333 	GRSR_ContextSensitive = 0x02,             // bit 1 set
334 	GRSR_Ligatures = 0x04,                    // bit 2 set
335 	GRSR_ContextSensitiveAndLigatures = 0x06, // bit 1, 2 set
336 	GRSR_Unknown = 0xef,                      // bits 0-6 set, initial value for text in our runs
337 	GRSR_Error = 0xff                         // bits 0-7 set
338 };
339 
340 /*
341   GR_Graphics is a portable interface to a simple 2-d graphics layer.  It is not
342   an attempt at a general purpose portability layer.  Rather, it contains only
343   functions which are needed.
344 */
345 
346 #define GR_OC_LEFT_FLUSHED 0x40000000 // flip bit 31
347 #define GR_OC_MAX_WIDTH    0x3fffffff
348 
349 class ABI_EXPORT AllCarets
350 {
351 	friend class GR_Graphics;
352  public:
353 	AllCarets(GR_Graphics * pG,
354 			  GR_Caret ** pCaret,
355 			  UT_GenericVector<GR_Caret *>* vecCarets  );
~AllCarets()356 	virtual ~AllCarets(){}
357 	GR_Caret *  getBaseCaret(void);
358 	void	    enable(void);
359 	void		disable(bool bNoMulti = false);
360 	void		setBlink(bool bBlink);
361 	void        JustErase(UT_sint32 xPoint,UT_sint32 yPoint);
362 	void        setWindowSize(UT_uint32 width, UT_uint32 height);
363 	void		setCoords(UT_sint32 x, UT_sint32 y, UT_uint32 h,
364 						  UT_sint32 x2 = 0, UT_sint32 y2 = 0, UT_uint32 h2 = 0,
365 						  bool bPointDirection = false,
366 						  const UT_RGBColor * pClr = NULL);
367 	void		setInsertMode (bool mode);
368 	void		forceDraw(void);
369 	bool        doBlinkIfNeeded(void);
370 	void        setPendingBlink(void);
371 
372  private:
373 	GR_Graphics * m_pG;
374 	GR_Caret **    m_pLocalCaret;
375 	UT_GenericVector<GR_Caret *>* m_vecCarets;
376 };
377 
378 
379 class ABI_EXPORT GR_Graphics
380 {
381 	friend class GR_Painter;
382 	friend class GR_Caret;
383 	friend class AllCarets;
384  public:
385 	virtual ~GR_Graphics();
386 
387 	// the static method allows us to retrive the the class id for
388 	// purposes of registration; we also need the virtual to identify
389 	// the class from a generic GR_Graphics pointer
390 //	static UT_uint32 s_getClassId() {UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); return GRID_UNKNOWN;}
391 	virtual UT_uint32 getClassId() = 0;
392 
getCapability()393 	virtual GR_Capability getCapability() {UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); return GRCAP_UNKNOWN;}
394 #if 0
395 	// the following two static functions have to be implemented by all
396 	// derrived classes and registered with GR_GraphicsFactory
397 	static const char *    graphicsDescriptor(void){UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); return "???";}
398 	static GR_Graphics *   graphicsAllocator(GR_AllocInfo&){UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); return NULL;}
399 #endif
400 
401 	AllCarets *	allCarets();
402 	void		disableAllCarets();
403 	void		enableAllCarets();
404 
405 	UT_sint32	tdu(UT_sint32 layoutUnits) const;
406 	UT_sint32	tlu(UT_sint32 deviceUnits) const;
407 	double	    tduD(double layoutUnits) const;
408 	double  	tluD(double deviceUnits) const;
antiAliasAlways(bool bAntiAlias)409 	void        antiAliasAlways(bool bAntiAlias)
410 	{ m_bAntiAliasAlways = bAntiAlias;}
getAntiAliasAlways(void)411 	bool        getAntiAliasAlways(void)
412 	{ return m_bAntiAliasAlways;}
413 
414 	/*!
415 		Font units to layout units. Returns the dimension in layout units since font
416 		are not Zoomed
417 	 */
418 	UT_sint32	ftlu(UT_sint32 fontUnits) const;
419 	double		ftluD(double fontUnits) const;
420 
421 	virtual void      setFont(const GR_Font* pFont) = 0;
422     virtual void      clearFont(void) = 0;
423 	virtual UT_uint32 getFontAscent() = 0;
424 	virtual UT_uint32 getFontDescent() = 0;
425 	virtual UT_uint32 getFontHeight() = 0;
426 	void              invalidateCache(void);
canQuickPrint(void)427 	virtual bool      canQuickPrint(void) const { return false;}
428 	virtual UT_uint32 measureString(const UT_UCSChar*s,
429 									int iOffset,
430 									int num,
431 									UT_GrowBufElement* pWidths, UT_uint32 *height = 0);
432 
433 	virtual UT_sint32 measureUnRemappedChar(const UT_UCSChar c, UT_uint32 * height = 0) = 0;
434 	virtual void getCoverage(UT_NumberVector& coverage) = 0;
435 
436 	/* GR_Font versions of the above -- TODO: should I add drawChar* methods too? */
437 	virtual UT_uint32 getFontAscent(const GR_Font *)  = 0;
438 	virtual UT_uint32 getFontDescent(const GR_Font *) = 0;
439 	virtual UT_uint32 getFontHeight(const GR_Font *)  = 0;
getResolutionRatio(void)440 	virtual double    getResolutionRatio(void) const {return 1.0;}
441 
442 	void         getMaxCharacterDimension (const UT_UCSChar*s, UT_uint32 Length, UT_uint32 &width, UT_uint32 &height);
443 
444 	virtual void      setColor(const UT_RGBColor& clr) = 0;
445 	virtual void      getColor(UT_RGBColor& clr) = 0;
446 	virtual GR_Font*  getGUIFont() = 0;
447 
448 	GR_Font*  findFont(const char* pszFontFamily,
449 					   const char* pszFontStyle,
450 					   const char* pszFontVariant,
451 					   const char* pszFontWeight,
452 					   const char* pszFontStretch,
453 					   const char* pszFontSize,
454 					   const char* pszLang);
455 
456 	/* Static 'virtual' -- if you are providing an implementation for this
457 	 * function in a derrived graphics class, please define
458 	 * XAP_HAVE_GR_findNearestFont in platform xap_*Features.h file
459 	 */
460 #ifdef XAP_HAVE_GR_findNearestFont
461 	static const char* findNearestFont(const char* pszFontFamily,
462 									   const char* pszFontStyle,
463 									   const char* pszFontVariant,
464 									   const char* pszFontWeight,
465 									   const char* pszFontStretch,
466 									   const char* pszFontSize,
467 									   const char* pszLang);
468 #else
findNearestFont(const char * pszFontFamily,const char *,const char *,const char *,const char *,const char *,const char *)469 	static const char* findNearestFont(const char* pszFontFamily,
470 									   const char* /*pszFontStyle*/,
471 									   const char* /*pszFontVariant*/,
472 									   const char* /*pszFontWeight*/,
473 									   const char* /*pszFontStretch*/,
474 									   const char* /*pszFontSize*/,
475 									   const char* /*pszLang*/)
476 		{return pszFontFamily;}
477 #endif
478 
479 	const char *      invertDimension(UT_Dimension, double) const;
480 
481 	bool              scaleDimensions(const char * szLeftIn,
482 									  const char * szWidthIn,
483 									  UT_uint32 iWidthAvail,
484 									  UT_sint32 * piLeft,
485 									  UT_uint32 * piWidth) const;
486 
487    	virtual GR_Image* createNewImage(const char* pszName,
488 									 const UT_ByteBuf* pBB,
489 									 const std::string& mimetype,
490 									 UT_sint32 iWidth,
491 									 UT_sint32 iHeight,
492 									 GR_Image::GRType iType = GR_Image::GRT_Raster);
493 
494 	virtual void      setLineWidth(UT_sint32) = 0;
495 
496 	virtual void      setClipRect(const UT_Rect* pRect) = 0;
getClipRect(void)497 	const UT_Rect *   getClipRect(void) const { return m_pRect.get();}
498 	virtual void      scroll(UT_sint32, UT_sint32) = 0;
499 	virtual void      scroll(UT_sint32 x_dest,
500 							 UT_sint32 y_dest,
501 							 UT_sint32 x_src,
502 							 UT_sint32 y_src,
503 							 UT_sint32 width,
504 							 UT_sint32 height) = 0;
505 
506 	typedef enum { DGP_SCREEN, DGP_PAPER, DGP_OPAQUEOVERLAY } Properties;
507 
508 	typedef enum
509 	  {
510 	    JOIN_MITER,
511 	    JOIN_ROUND,
512 	    JOIN_BEVEL
513 	  } JoinStyle ;
514 
515 	typedef enum
516 	  {
517 	    CAP_BUTT,
518 	    CAP_ROUND,
519 	    CAP_PROJECTING
520 	  } CapStyle ;
521 
522 	typedef enum
523 	  {
524 	    LINE_SOLID,
525 	    LINE_ON_OFF_DASH,
526 	    LINE_DOUBLE_DASH,
527 		LINE_DOTTED
528 	  } LineStyle ;
529 
530 	virtual void setLineProperties ( double inWidthPixels,
531 					 JoinStyle inJoinStyle = JOIN_MITER,
532 					 CapStyle inCapStyle   = CAP_BUTT,
533 					 LineStyle inLineStyle = LINE_SOLID ) ;
534 
535 	virtual bool      queryProperties(GR_Graphics::Properties gp) const = 0;
536 	/* the following 3 are only used for printing */
537 
538 	virtual bool      startPrint(void) = 0;
539 
540 	virtual bool      startPage(const char * szPageLabel,
541 								UT_uint32 pageNumber,
542 								bool bPortrait,
543 								UT_uint32 iWidth,
544 								UT_uint32 iHeight) = 0;
545 
546 	virtual bool      endPrint(void) = 0;
547 
548 	virtual void      flush(void);
549 
550 	/* specific color space support */
551 
552 	typedef enum { GR_COLORSPACE_COLOR,
553 				   GR_COLORSPACE_GRAYSCALE,
554 				   GR_COLORSPACE_BW
555 	} ColorSpace;
556 
557 	virtual void      setColorSpace(GR_Graphics::ColorSpace c) = 0;
558 	virtual GR_Graphics::ColorSpace getColorSpace(void) const = 0;
559 
560 	/* multiple cursor support */
561 
562 	typedef enum { GR_CURSOR_INVALID=0,
563 				   GR_CURSOR_DEFAULT,
564 				   GR_CURSOR_IBEAM,
565 				   GR_CURSOR_RIGHTARROW,
566 				   GR_CURSOR_IMAGE,
567 				   GR_CURSOR_IMAGESIZE_NW,
568 				   GR_CURSOR_IMAGESIZE_N,
569 				   GR_CURSOR_IMAGESIZE_NE,
570 				   GR_CURSOR_IMAGESIZE_E,
571 				   GR_CURSOR_IMAGESIZE_SE,
572 				   GR_CURSOR_IMAGESIZE_S,
573 				   GR_CURSOR_IMAGESIZE_SW,
574 				   GR_CURSOR_IMAGESIZE_W,
575 				   GR_CURSOR_LEFTRIGHT,
576 				   GR_CURSOR_UPDOWN,
577 				   GR_CURSOR_EXCHANGE,
578 				   GR_CURSOR_GRAB,
579 				   GR_CURSOR_LINK,
580 				   GR_CURSOR_WAIT,
581 				   GR_CURSOR_LEFTARROW,
582 				   GR_CURSOR_VLINE_DRAG,
583 				   GR_CURSOR_HLINE_DRAG,
584 				   GR_CURSOR_CROSSHAIR,
585 		                   GR_CURSOR_DOWNARROW,
586 		                   GR_CURSOR_DRAGTEXT,
587 		                   GR_CURSOR_COPYTEXT
588 	} Cursor;
589 
590 	virtual void      setCursor(GR_Graphics::Cursor c) = 0;
591 	virtual GR_Graphics::Cursor getCursor(void) const = 0;
592 
593 	virtual void      setZoomPercentage(UT_uint32 iZoom);
getZoomPercentage(void)594 	inline UT_uint32  getZoomPercentage(void) const {return m_iZoomPercentage; }
getResolution(void)595 	static UT_uint32  getResolution(void) { return UT_LAYOUT_RESOLUTION; }
setPortrait(bool b)596 	inline void       setPortrait (bool b) {m_bIsPortrait = b;}
isPortrait(void)597 	inline bool       isPortrait (void) const {return m_bIsPortrait;}
598 
599 	typedef enum { CLR3D_Foreground=0,				/* color of text/foreground on a 3d object */
600 				   CLR3D_Background=1,				/* color of face/background on a 3d object */
601 				   CLR3D_BevelUp=2,					/* color of bevel-up  */
602 				   CLR3D_BevelDown=3,				/* color of bevel-down */
603 				   CLR3D_Highlight=4				/* color half-way between up and down */
604 	} GR_Color3D;
605 #define COUNT_3D_COLORS 5
606 
607 	virtual void      setColor3D(GR_Color3D c) = 0;
getColor3D(GR_Color3D,UT_RGBColor &)608 	virtual bool      getColor3D(GR_Color3D /*name*/, UT_RGBColor & /*color*/)
609 	{ return false; }
610 
getTransform()611 	const GR_Transform & getTransform() const {return m_Transform;}
612 
613 	/* returns true on success, false on failure */
setTransform(const GR_Transform & tr)614 	bool              setTransform(const GR_Transform & tr)
615 	                     {
616 							 bool ret = _setTransform(tr);
617 							 if(!ret)
618 								 return false;
619 							 m_Transform = tr;
620 							 return true;
621 						 }
622 
createCaret()623 	void              createCaret()
624 		{
625 			UT_ASSERT_HARMLESS(!m_pCaret);
626 			m_pCaret = new GR_Caret(this);
627 		}
628 
629 	GR_Caret *        createCaret(const std::string& sID);
630 	GR_Caret *        getCaret(const std::string& sID) const;
631 	GR_Caret *        getNthCaret(UT_sint32 i) const;
632 	void              removeCaret(const std::string& sID);
633 
634 	virtual void	  saveRectangle(UT_Rect & r, UT_uint32 iIndx) = 0;
635 	virtual void	  restoreRectangle(UT_uint32 iIndx) = 0;
636 	virtual UT_uint32 getDeviceResolution(void) const = 0;
637 //
638 // Use these methods to fix off by 1 errors while scrolling. Add the
639 // the logical difference to these first, then calculate how much
640 // the screen needs to scroll in device units
641 //
getPrevYOffset(void)642 	UT_sint32         getPrevYOffset(void) const { return m_iPrevYOffset;}
getPrevXOffset(void)643 	UT_sint32         getPrevXOffset(void) const { return m_iPrevXOffset;}
setPrevYOffset(UT_sint32 y)644 	void              setPrevYOffset(UT_sint32 y) { m_iPrevYOffset = y;}
setPrevXOffset(UT_sint32 x)645 	void              setPrevXOffset(UT_sint32 x) { m_iPrevXOffset = x;}
646 
647 	UT_sint32         _tduX(UT_sint32 layoutUnits) const;
648 
649 
650 	///////////////////////////////////////////////////////////////////
651 	// complex script processing; see default implementations of these
652 	// functions for documentation
653 	//
654 	virtual bool itemize(UT_TextIterator & text, GR_Itemization & I) VIRTUAL_SFX;
655 
656 	// translates GR_ShapingInfo into GR_RenderInfo which then can be
657 	// passed to renderChars()
658 	virtual bool shape(GR_ShapingInfo & si, GR_RenderInfo *& ri) VIRTUAL_SFX;
659 
660 	// like drawChars, except uses generic (platform specific) input
661 	// the default implementation simply maps to drawChars and needs
662 	// to be replaced by platform code
663 	virtual void prepareToRenderChars(GR_RenderInfo & ri) VIRTUAL_SFX;
664 	virtual void renderChars(GR_RenderInfo & ri) VIRTUAL_SFX;
665 
666 	virtual void appendRenderedCharsToBuff(GR_RenderInfo & ri, UT_GrowBuf & buf) const VIRTUAL_SFX;
667 	virtual void measureRenderedCharWidths(GR_RenderInfo & ri) VIRTUAL_SFX;
668 
669 	// expects ri.m_iOffset set to the run offset condsidered for break
670 	//         ri.m_pText set positioned at start of the run
671 	//         represented by ri, its uper limit set appropriately
672 	//         ri.m_iLength is set to the run length
673 	// iNext -- if break is not possible at the given offset, the
674 	//          class might return the next possible break offset in
675 	//          iNext, relative to start of the text represented by ri
676 	//          (not relative to m_iOffset); if the class does not
677 	//          know where the next break point lies, it should set
678 	//          iNext to -1; if it knows that there is no break in this run, it should set
679 	//          iNext to -2
680 	// bAfter indicates whether we are quering for a break after the character at given offset
681 
682 	virtual bool canBreak(GR_RenderInfo & ri, UT_sint32 &iNext, bool bAfter) VIRTUAL_SFX;
683 
684 	// indicates if special caret positioning has to be done for the run of text; this allows us
685 	// to speed things up when this is not needed
needsSpecialCaretPositioning(GR_RenderInfo &)686 	virtual bool needsSpecialCaretPositioning(GR_RenderInfo & /*ri*/) VIRTUAL_SFX {return false;}
687 
688 	// adjusts caret position if given script restricts where caret can be placed
689 	// the caller has to set initial position within the run in ri.m_iOffset, overall length of
690 	// the run in ri.m_iLength and provide a text iterator over the text of the run in ri.m_pText
691 	//
692 	// return value is the adjusted offset
693 	// the default implementation simply returns the passed value
694 	virtual UT_uint32 adjustCaretPosition(GR_RenderInfo & ri, bool bForward) VIRTUAL_SFX;
695 
696 	// Adjusts position for delete if given script restricts deletion to character clusters.
697 	// The caller has to set initial position within the run in ri.m_iOffset, overall length to be
698 	// deleted in ri.m_iLength and provide a text iterator over the text of the run in ri.m_pText
699 	// on return ri.m_iOffset contains the adjusted (run-relative) position and ri.m_iLength the count
700 	// the adjusted length of the delete
701 	//
702 	// the default implementation simply returns the passed value
703 	virtual void adjustDeletePosition(GR_RenderInfo & ri) VIRTUAL_SFX;
704 
705 	// the AbiWord line breaking was designed looking for breaks at the right edge of a character,
706 	// i.e., the character that can break is included with the left part of the split run.
707 	// the Uniscribe library, however, holds breaking info for left edge, and sometimes it is useful
708 	// to know what system we are dealing with.
nativeBreakInfoForRightEdge()709 	virtual bool nativeBreakInfoForRightEdge() VIRTUAL_SFX {return true;}
710 
711 	virtual UT_sint32 resetJustification(GR_RenderInfo & ri, bool bPermanent) VIRTUAL_SFX;
712 	virtual UT_sint32 countJustificationPoints(const GR_RenderInfo & ri) const VIRTUAL_SFX;
713 	virtual void justify(GR_RenderInfo & ri) VIRTUAL_SFX;
714 
715     virtual UT_uint32 XYToPosition(const GR_RenderInfo & ri, UT_sint32 x, UT_sint32 y) const VIRTUAL_SFX;
716     virtual void      positionToXY(const GR_RenderInfo & ri,
717 								   UT_sint32& x, UT_sint32& y,
718 								   UT_sint32& x2, UT_sint32& y2,
719 								   UT_sint32& height, bool& bDirection) const VIRTUAL_SFX;
720 
721 	// FIXME: this method should return a larger integer (or a floating point number)
722 	// because it might overflow in some cases, see bug 13709
723 	virtual UT_sint32 getTextWidth(GR_RenderInfo & ri) VIRTUAL_SFX;
724 
725 	// should be overriden by any classes implemented as plugins
726 	// NB: you must not use s_Version to store the version of derrived
727 	// classes, but have your own static variable for the derrived
728 	// class !!!
getVersion()729 	virtual const UT_VersionInfo & getVersion() const {UT_ASSERT_HARMLESS( UT_NOT_IMPLEMENTED ); return s_Version;}
getPaintCount(void)730 	UT_uint32         getPaintCount(void) const
731 		{ return  m_paintCount;}
732 
733 	/* all drawing should happen between calls to these two functions. this
734 	 * arranges for cairo contexts to be created/destroyed etc.  if you don't
735 	 * call these functions, bad things can and will happen */
736 	void beginPaint ();
737 	void endPaint ();
738 
739 	static GR_Graphics* newNullGraphics();
740 
741  protected:
742 
743 	GR_Graphics();
getCaret()744 	GR_Caret *        getCaret() { return m_pCaret; }
745 
746 	// todo: make these pure virtual
_beginPaint()747 	virtual void _beginPaint () {}
_endPaint()748 	virtual void _endPaint () {}
749 
750 	UT_sint32         _tduY(UT_sint32 layoutUnits) const;
751 	UT_sint32         _tduR(UT_sint32 layoutUnits) const;
752 
753 	void _destroyFonts ();
754 
755 	virtual GR_Font* _findFont(const char* pszFontFamily,
756 							   const char* pszFontStyle,
757 							   const char* pszFontVariant,
758 							   const char* pszFontWeight,
759 							   const char* pszFontStretch,
760 							   const char* pszFontSize,
761 							   const char* pszLang) = 0;
762 
763 	// only called by GR_Painter
764 	virtual void drawLine(UT_sint32 x1, UT_sint32 y1, UT_sint32 x2, UT_sint32 y2) = 0;
765 #if XAP_DONTUSE_XOR
766 #else
767 	virtual void xorLine(UT_sint32 x1, UT_sint32 y1, UT_sint32 x2, UT_sint32 y2) = 0;
768 #endif
769 	virtual void invertRect(const UT_Rect* pRect) = 0;
770 #if XAP_DONTUSE_XOR
771 #else
772 	void xorRect(UT_sint32 x, UT_sint32 y, UT_sint32 w, UT_sint32 h);
773 	void xorRect(const UT_Rect& r);
774 #endif
775 
776 	virtual void fillRect(GR_Image *pImg, const UT_Rect &src, const UT_Rect & dest);
777 	virtual void fillRect(const UT_RGBColor& c, const UT_Rect &r);
778 	virtual void fillRect(const UT_RGBColor& c, UT_sint32 x, UT_sint32 y,
779 						  UT_sint32 w, UT_sint32 h) = 0;
780 
781 	virtual void clearArea(UT_sint32 x, UT_sint32 y, UT_sint32 w, UT_sint32 h) = 0;
782 	virtual void drawImage(GR_Image* pImg, UT_sint32 xDest, UT_sint32 yDest);
783 	virtual void fillRect(GR_Color3D c, UT_Rect &r) = 0;
784 	virtual void fillRect(GR_Color3D c,
785 						  UT_sint32 x, UT_sint32 y,
786 						  UT_sint32 w, UT_sint32 h) = 0;
787 	virtual void polygon(UT_RGBColor& c, UT_Point *pts, UT_uint32 nPoints);
788 	virtual void polyLine(UT_Point * pts, UT_uint32 nPoints) = 0;
789 	virtual void drawGlyph(UT_uint32 glyph_idx, UT_sint32 xoff, UT_sint32 yoff) = 0;
790 	virtual void drawChars(const UT_UCSChar* pChars,
791 						   int iCharOffset,
792 						   int iLength,
793 						   UT_sint32 xoff,
794 						   UT_sint32 yoff,
795 						   int* pCharWidths = NULL) = 0;
796 
797 	virtual void drawCharsRelativeToBaseline(const UT_UCSChar* pChars,
798 											 int iCharOffset,
799 											 int iLength,
800 											 UT_sint32 xoff,
801 											 UT_sint32 yoff,
802 											 int* pCharWidths = NULL);
803 
804 	virtual GR_Image *	  genImageFromRectangle(const UT_Rect & r) = 0;
805 
806  private:
_setTransform(const GR_Transform &)807 	virtual bool _setTransform(const GR_Transform & /*tr*/)
808 		{
809 			UT_ASSERT_HARMLESS( UT_NOT_IMPLEMENTED );
810 			return false;
811 		}
812 
813  public:
814 	// TODO -- this should not be public, create access methods !!!
815 	//
816 	// Postscript context positions graphics wrt top of current PAGE, NOT
817 	// wrt top of document. The screen graphics engine, though positions
818 	// graphics wrt the top of the document, therefore if we are printing
819 	// page 5 we need to adjust the vertical position of the graphic in the
820 	// postscript image printing routine by (current_page_number-1) * page_height
821 	// I'm going to call this variable m_iRasterPosition, for want of a better name,
822 	// it's not acutally a rasterposition --- any better names would be a good idea,
823 	// I jusy can't think of one right now.
824 	UT_uint32         m_iRasterPosition;
825 
826  protected:
827 	UT_uint32	      m_iZoomPercentage;
828 	UT_uint32         m_iFontAllocNo;
829 
830 	static XAP_PrefsScheme *m_pPrefsScheme;
831 	static UT_uint32 m_uTick;
832 
833 	std::unique_ptr<const UT_Rect> m_pRect;
834 
835 	bool m_bHave3DColors;
836 
837 	UT_uint32 m_paintCount;
838 
839 	// Double buffering infrastructure.
840 
841 	// The default implementation here leads to no double buffering,
842 	// as they perform no action at all. Should be overriden in derived
843 	// classes
_DeviceContext_SwitchToBuffer()844 	virtual void _DeviceContext_SwitchToBuffer() { };
_DeviceContext_SwitchToScreen()845 	virtual void _DeviceContext_SwitchToScreen() { };
846 
847 	// returns the token for the current call
848 	bool beginDoubleBuffering();
849 
850 	// does the actual buffer-to-screen switch only when it gets
851 	// the correct token
852 	void endDoubleBuffering(bool token);
853 
854 	// SUSPEND / RESUME drawings infrastructure
855 	// Drawing code (through gr_Graphics) will have no effect between SUSPEND - RESUME.
856 	// The default implementation does not suspend anything
857 	// (ie. changes are still taking effect)
858 
_DeviceContext_SuspendDrawing()859 	virtual void _DeviceContext_SuspendDrawing() { };
_DeviceContext_ResumeDrawing()860 	virtual void _DeviceContext_ResumeDrawing() { };
861 
862 	bool suspendDrawing();
863 	void resumeDrawing(bool token);
864 
865 	// Device context switch management
866 	bool m_bDoubleBufferingActive;
867 	bool m_bDrawingSuspended;
868 
869 	typedef enum {
870 		SWITCHED_TO_BUFFER = 0,
871 		DRAWING_SUSPENDED
872 	} DeviceContextSwitchType;
873 
874 	UT_NumberStack m_DCSwitchManagementStack;
875 
876  private:
877 	GR_Caret *		 m_pCaret;
878     bool             _PtInPolygon(UT_Point * pts,UT_uint32 nPoints,UT_sint32 x,UT_sint32 y);
879     bool             m_bIsPortrait;
880 	bool             m_bSpawnedRedraw;
881 	UT_Rect          m_PendingExposeArea;
882 	UT_Rect          m_RecentExposeArea;
883 	bool             m_bExposePending;
884 	bool             m_bIsExposedAreaAccessed;
885 	bool             m_bDontRedraw;
886 	bool             m_bDoMerge;
887 //
888 // These hold the previous x and Y offset calculated from the scrolling code
889 // in Logical units. We need them to avoid off by 1 errors in scrolling.
890 //
891 	UT_sint32        m_iPrevYOffset;
892 	UT_sint32        m_iPrevXOffset;
893 	GR_Transform     m_Transform;
894 
895 	typedef std::map<std::string, GR_Font*> FontCache;
896 	FontCache  m_hashFontCache;
897 
898 	static UT_VersionInfo   s_Version;
899 	static UT_uint32        s_iInstanceCount;
900 	static UT_UCS4Char      s_cDefaultGlyph;
901 	UT_GenericVector<GR_Caret *>  m_vecCarets;
902 	AllCarets               m_AllCarets;
903 	bool                    m_bAntiAliasAlways;
904 };
905 
906 #endif /* GR_GRAPHICS_H */
907