1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: t -*- */
2 /* AbiWord
3  * Copyright (C) 2004-6 Tomas Frydrych <dr.tomas@yahoo.co.uk>
4  * Copyright (C) 2009 Hubert Figuiere
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_UNIX_PANGOGRAPHICS_H
23 #define GR_UNIX_PANGOGRAPHICS_H
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #include <vector>
30 
31 #include "ut_types.h"
32 #include "ut_color.h"
33 #include "ut_string_class.h"
34 #include "gr_RenderInfo.h"
35 
36 #include <cairo.h>
37 #include <pango/pango.h>
38 
39 // we do not want this to be a plugin for now
40 #define GR_UNIXPANGO_BUILTIN
41 
42 #ifndef GR_UNIXPANGO_BUILTIN
43 #define PLUGIN_NAME "Cairo Pango graphics"
44 #endif
45 
46 /************************************************************************/
47 /************************************************************************/
48 
49 class GR_PangoRenderInfo;
50 class GR_CairoGraphics;
51 class XAP_Frame;
52 
53 class GR_CairoPatternImpl
54 	: public UT_ColorPatImpl
55 {
56 public:
57 	GR_CairoPatternImpl(const char * fileName);
58 	// don't take ownership
59 	GR_CairoPatternImpl(cairo_surface_t * surf);
60 	GR_CairoPatternImpl(const GR_CairoPatternImpl &);
61 	virtual ~GR_CairoPatternImpl();
62     virtual UT_ColorPatImpl * clone() const;
getPattern()63 	cairo_pattern_t *getPattern() const
64 		{
65 			return m_pattern;
66 		}
67 private:
68 	GR_CairoPatternImpl & operator=(const GR_CairoPatternImpl &);
69 	cairo_pattern_t *m_pattern;
70 };
71 
72 
73 class GR_CairoVectorImage
74 	: public GR_VectorImage
75 {
76 public:
77 	virtual void cairoSetSource(cairo_t *) = 0;
78 	virtual void renderToCairo(cairo_t*) = 0;
79 };
80 
81 /** An abstract Cairo image */
82 class GR_CairoRasterImage
83 	: public GR_RasterImage
84 {
85 public:
86 	virtual GR_Image * createImageSegment(GR_Graphics * pG,const UT_Rect & rec);
87 	virtual void cairoSetSource(cairo_t *) = 0;
88 protected:
89 	// called by createImageSegment()
90 	virtual GR_CairoRasterImage *makeSubimage(const std::string & n,
91 											  UT_sint32 x, UT_sint32 y,
92 											  UT_sint32 w, UT_sint32 h) const = 0;
93 };
94 
95 class ABI_EXPORT GR_PangoFont : public GR_Font
96 {
97 
98   public:
99 	GR_PangoFont(const char * pDesc, double dSize,
100 					 GR_CairoGraphics * pG,
101 					 const char * pLang,
102 					 bool bGuiFont = false);
103 
104 	virtual ~GR_PangoFont();
105 
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_UCS4Char cChar) const;
111 	virtual bool      doesGlyphExist(UT_UCS4Char g) const;
112 	virtual bool      glyphBox(UT_UCS4Char g, UT_Rect & rec, GR_Graphics * pG);
getPangoFont()113 	PangoFont *       getPangoFont() const {return m_pf;}
getPangoLayoutFont()114 	PangoFont *       getPangoLayoutFont() const {return m_pLayoutF;}
115 
116 	void              reloadFont(GR_CairoGraphics * pG);
getPointSize()117 	double            getPointSize() const {return m_dPointSize;}
getZoom()118 	UT_uint32         getZoom() const {return m_iZoom;}
isGuiFont()119 	bool              isGuiFont () const {return m_bGuiFont;}
getDescription()120 	const UT_String & getDescription() const {return m_sDesc;}
121 
122 	virtual const char* getFamily() const;
getPangoDescription()123 	const PangoFontDescription * getPangoDescription() const {return m_pfdLay;}
124 
125 	// ascent/descent in layout units
getAscent()126 	UT_uint32         getAscent() const {return m_iAscent;}
getDescent()127 	UT_uint32         getDescent() const {return m_iDescent;}
128 
129 	PangoCoverage *   getPangoCoverage() const;
getPangoLanguage()130 	PangoLanguage *   getPangoLanguage() const {return m_pPLang;}
131 	void              setLanguage(const char * pLang);
132   private:
133 	UT_String              m_sDesc;
134 	UT_String              m_sLayoutDesc;
135 	double                 m_dPointSize;
136 	UT_uint32              m_iZoom;
137 	PangoFont *            m_pf;
138 	bool                   m_bGuiFont;
139 	mutable PangoCoverage *m_pCover;
140 	PangoFontDescription * m_pfdDev;
141 	PangoFontDescription * m_pfdLay;
142 	PangoLanguage *        m_pPLang;
143 
144 	UT_uint32              m_iAscent;
145 	UT_uint32              m_iDescent;
146 	PangoFont *            m_pLayoutF;
147 };
148 
149 class GR_PangoRenderInfo;
150 
151 
152 class ABI_EXPORT GR_CairoAllocInfo
153 	: public GR_AllocInfo
154 {
155 public:
GR_CairoAllocInfo(bool bPreview,bool bPrinter,bool double_buffered)156 	GR_CairoAllocInfo(bool bPreview, bool bPrinter, bool double_buffered)
157 		: m_bPreview(bPreview),
158 		  m_bPrinter(bPrinter),
159 		  m_double_buffered(double_buffered)
160 	{
161 	}
getType()162 	virtual GR_GraphicsId getType() const {return GRID_UNIX;}
isPrinterGraphics()163 	virtual bool isPrinterGraphics() const {return m_bPrinter;}
164 	virtual cairo_t *createCairo() = 0;
165 
166 	bool            m_bPreview;
167 	bool            m_bPrinter;
168 	bool m_double_buffered;
169 };
170 
171 
172 class ABI_EXPORT GR_CairoGraphics : public GR_Graphics
173 {
174 	friend class GR_UnixImage;
175 
176 	// all constructors are protected; instances must be created via
177 	// GR_GraphicsFactory
178 public:
179 	virtual ~GR_CairoGraphics();
180 
getCapability()181 	virtual GR_Capability  getCapability() {return GRCAP_SCREEN_ONLY;}
182 
183 	virtual UT_sint32      measureUnRemappedChar(const UT_UCSChar c, UT_uint32 * height = 0);
184 
185 	virtual void		   drawChars(const UT_UCSChar* pChars,
186 									 int iCharOffset, int iLength,
187 									 UT_sint32 xoff, UT_sint32 yoff,
188 									 int * pCharWidth);
189 
190 	virtual void           drawGlyph(UT_uint32 glyph_idx,
191 									 UT_sint32 xoff, UT_sint32 yoff);
192 
193 	virtual UT_uint32      measureString(const UT_UCSChar* s, int iOffset,
194 										 int num,  UT_GrowBufElement* pWidths, UT_uint32 * height = 0);
195 
196 	virtual GR_Font*	   getDefaultFont(UT_String& fontFamily,
197 										  const char * pszLang);
198 
199 	virtual void           setFont(const GR_Font *);
clearFont(void)200 	virtual void           clearFont(void) {m_pPFont = NULL;}
201 
202 	virtual void           setZoomPercentage(UT_uint32 iZoom);
203 
204 	///////////////////////////////////////////////////////////////////
205 	// complex script processing
206 	//
207 	virtual bool itemize(UT_TextIterator & text, GR_Itemization & I);
208 	virtual bool shape(GR_ShapingInfo & si, GR_RenderInfo *& ri);
209 	virtual void prepareToRenderChars(GR_RenderInfo & ri);
210 	virtual void renderChars(GR_RenderInfo & ri);
211 	virtual void measureRenderedCharWidths(GR_RenderInfo & ri);
212 	virtual void appendRenderedCharsToBuff(GR_RenderInfo & ri, UT_GrowBuf & buf) const;
213 	virtual bool canBreak(GR_RenderInfo & ri, UT_sint32 &iNext, bool bAfter);
214 
215 	virtual bool needsSpecialCaretPositioning(GR_RenderInfo & ri);
216 	virtual UT_uint32 adjustCaretPosition(GR_RenderInfo & ri, bool bForward);
217 	virtual void adjustDeletePosition(GR_RenderInfo & ri);
nativeBreakInfoForRightEdge()218 	virtual bool nativeBreakInfoForRightEdge() {return false;}
219 
220 	virtual UT_sint32 resetJustification(GR_RenderInfo & ri, bool bPermanent);
221 	virtual UT_sint32 countJustificationPoints(const GR_RenderInfo & ri) const;
222 	virtual void      justify(GR_RenderInfo & ri);
223 
224 	virtual UT_uint32 XYToPosition(const GR_RenderInfo & ri, UT_sint32 x, UT_sint32 y) const;
225 	virtual void      positionToXY(const GR_RenderInfo & ri,
226 								   UT_sint32& x, UT_sint32& y,
227 								   UT_sint32& x2, UT_sint32& y2,
228 								   UT_sint32& height, bool& bDirection) const;
229 	virtual UT_sint32 getTextWidth(GR_RenderInfo & ri);
230 
getVersion()231 	virtual const UT_VersionInfo & getVersion() const {return s_Version;}
232 
233 	virtual void setColor(const UT_RGBColor& clr);
234 	virtual void getColor(UT_RGBColor &clr);
235 
getFontMap()236 	PangoFontMap * getFontMap() const {return m_pFontMap;}
getContext()237 	PangoContext * getContext() const {return m_pContext;}
getLayoutFontMap()238 	PangoFontMap * getLayoutFontMap() const {return m_pLayoutFontMap;}
getLayoutContext()239 	PangoContext * getLayoutContext() const {return m_pLayoutContext;}
240 
241 	virtual UT_uint32 getFontAscent();
242 	virtual UT_uint32 getFontDescent();
243 	virtual UT_uint32 getFontHeight();
244 
245 	virtual UT_uint32 getFontAscent(const GR_Font *);
246 	virtual UT_uint32 getFontDescent(const GR_Font *);
247 	virtual UT_uint32 getFontHeight(const GR_Font *);
248 
249 	virtual void		fillRect(GR_Color3D c,
250 								 UT_sint32 x, UT_sint32 y,
251 								 UT_sint32 w, UT_sint32 h);
252 	virtual void		fillRect(GR_Color3D c, UT_Rect &r);
253 	virtual void		polygon(UT_RGBColor& c,UT_Point *pts,UT_uint32 nPoints);
254 	virtual void		clearArea(UT_sint32, UT_sint32, UT_sint32, UT_sint32);
255 	virtual void		drawImage(GR_Image* pImg, UT_sint32 xDest, UT_sint32 yDest);
256 	virtual void		xorLine(UT_sint32, UT_sint32, UT_sint32, UT_sint32);
257 	virtual void		polyLine(UT_Point * pts, UT_uint32 nPoints);
258 	virtual void		fillRect(const UT_RGBColor& c,
259 								 UT_sint32 x, UT_sint32 y,
260 								 UT_sint32 w, UT_sint32 h);
261 	virtual void		invertRect(const UT_Rect* pRect);
262 	virtual void		drawLine(UT_sint32, UT_sint32, UT_sint32, UT_sint32);
263 
isDingbat(void)264 	bool isDingbat(void) const {return m_bIsDingbat;}
isSymbol(void)265 	bool isSymbol(void) const {return m_bIsSymbol;};
266 
267 	void resetFontMapResolution(void);
268 
269 	virtual GR_Font* _findFont(const char* pszFontFamily,
270 							   const char* pszFontStyle,
271 							   const char* pszFontVariant,
272 							   const char* pszFontWeight,
273 							   const char* pszFontStretch,
274 							   const char* pszFontSize,
275 							   const char* pszLang);
276 
277 	virtual void getCoverage(UT_NumberVector& coverage);
278 	virtual void setLineWidth(UT_sint32);
279 	virtual void setClipRect(const UT_Rect* pRect);
280 	virtual UT_uint32 getDeviceResolution(void) const;
getResolutionRatio(void)281 	double    getResolutionRatio(void) const { return 1.0;}
282 
283 	static  const std::vector<std::string> &       getAllFontNames(void);
284 	static  UT_uint32                         getAllFontCount();
285 	virtual GR_Font * getDefaultFont(GR_Font::FontFamilyEnum f = GR_Font::FF_Roman,
286 									 const char * pszLang = NULL);
287 
288 	int dtpu(int d) const;
289 	int ptdu(int p) const;
290 	int ptlu(int p) const;
291 	int ptlunz(int p) const;
292 	int ltpu(int l) const;
293 	int ltpunz(int l) const;
294 	int pftlu(int pf) const;
295 
296 	virtual bool		queryProperties(GR_Graphics::Properties gp) const;
297 //	virtual GR_Image*	createNewImage(const char* pszName,
298 //									   const UT_ByteBuf* pBB,
299 //									   UT_sint32 iDisplayWidth,
300 //									   UT_sint32 iDisplayHeight,
301 //									   GR_Image::GRType =GR_Image::GRT_Raster);
302 
303   	virtual bool		startPrint(void);
304 	virtual bool		endPrint(void);
305 	virtual bool		startPage(const char * szPageLabel,
306 								  UT_uint32 pageNumber,
307 								  bool bPortrait,
308 								  UT_uint32 iWidth, UT_uint32 iHeight);
309 
310 	virtual void		setColorSpace(GR_Graphics::ColorSpace c);
311 	virtual GR_Graphics::ColorSpace getColorSpace(void) const;
312 
313 	// virtual void		setCursor(GR_Graphics::Cursor c);
314 	virtual GR_Graphics::Cursor getCursor(void) const;
315 
316 	virtual void		setColor3D(GR_Color3D c);
317 	virtual bool		getColor3D(GR_Color3D name, UT_RGBColor &color);
318 
319 	// virtual void		scroll(UT_sint32, UT_sint32);
320 	// virtual void		scroll(UT_sint32 x_dest, UT_sint32 y_dest,
321 	//						   UT_sint32 x_src, UT_sint32 y_src,
322 	//						   UT_sint32 width, UT_sint32 height);
323 
324 	virtual void	    	saveRectangle(UT_Rect & r, UT_uint32 iIndx);
325 	virtual void	    	restoreRectangle(UT_uint32 iIndx);
326 	// virtual GR_Image *  genImageFromRectangle(const UT_Rect & r);
327 
328 	virtual void setLineProperties(double inWidth,
329 					 GR_Graphics::JoinStyle inJoinStyle = JOIN_MITER,
330 					 GR_Graphics::CapStyle inCapStyle   = CAP_BUTT,
331 					 GR_Graphics::LineStyle inLineStyle = LINE_SOLID);
332 	cairo_t* getCairo ();
333 	void setCairo(cairo_t *cr);
334 
335 	static UT_uint32 getDefaultDeviceResolution();
336 
337   protected:
338 	// setup the graphics properties like color and clip if they have been set
339 	void _setProps();
340 	virtual void		_resetClip(void);
341 
342 	// this is called to get the surface out of what is drawning.
343 	static cairo_surface_t * _getCairoSurfaceFromContext(cairo_t *cr,
344 												const cairo_rectangle_t & rect);
345 	static void _setSource(cairo_t *, const UT_RGBColor &);
346 
347 	// all instances have to be created via GR_GraphicsFactory; see gr_Graphics.h
348 	GR_CairoGraphics(cairo_t *cr, UT_uint32 iDeviceResolution);
349 	GR_CairoGraphics();
350 	inline bool _scriptBreak(GR_PangoRenderInfo &ri);
351 
352 	void _scaleCharacterMetrics(GR_PangoRenderInfo & RI);
353 	void _scaleJustification(GR_PangoRenderInfo & RI);
354 
355 	inline UT_uint32 _measureExtent (PangoGlyphString * pg,
356 									 PangoFont * pf,
357 									 UT_BidiCharType iDir,
358 									 const char * pUtf8,
359 									 int * & pLogOffsets,
360 									 UT_sint32 & iStart,
361 									 UT_sint32 & iEnd);
362 
363 	inline int * _calculateLogicalOffsets (PangoGlyphString * pGlyphs,
364 										   UT_BidiCharType iVisDir,
365 										   const char * pUtf8);
366 
_setIsSymbol(bool b)367 	void         _setIsSymbol(bool b) {m_bIsSymbol = b;}
_setIsDingbat(bool b)368 	void         _setIsDingbat(bool b) {m_bIsDingbat = b;}
369 
370 	PangoFont *  _adjustedPangoFont (GR_PangoFont * pFont, PangoFont * pf);
371 	PangoFont *  _adjustedLayoutPangoFont (GR_PangoFont * pFont, PangoFont * pf);
372 
373 	double            _tdudX(UT_sint32 layoutUnits) const;
374 	double            _tdudY(UT_sint32 layoutUnits) const;
375 
376 	PangoFontMap *    m_pFontMap;
377 	PangoContext *    m_pContext;
378 	PangoFontMap *    m_pLayoutFontMap;
379 	PangoContext *    m_pLayoutContext;
380 	GR_PangoFont* m_pPFont;
381 	GR_PangoFont* m_pPFontGUI;
382 
383 	// adjusted device front caching
384 	PangoFont *       m_pAdjustedPangoFont;
385 	PangoFontDescription* m_pAdjustedPangoFontDescription;
386 	UT_sint32         m_iAdjustedPangoFontSize;
387 
388 	// adjusted layout font caching
389 	PangoFont *       m_pAdjustedLayoutPangoFont;
390 	PangoFontDescription* m_pAdjustedLayoutPangoFontDescription;
391 	UT_sint32         m_iAdjustedLayoutPangoFontSize;
392 
393 	UT_uint32         m_iDeviceResolution;
394 
395 	cairo_t	*         m_cr;
396 
397 	GR_Graphics::Cursor	    m_cursor;
398 	GR_Graphics::ColorSpace	m_cs;
399 
400 	UT_RGBColor		m_3dColors[COUNT_3D_COLORS];
401 
402 	UT_RGBColor		m_curColor;
403 	bool            m_curColorDirty;
404 	bool            m_clipRectDirty;
405 	double                 m_lineWidth;
406 	GR_Graphics::JoinStyle m_joinStyle;
407 	GR_Graphics::CapStyle  m_capStyle;
408 	GR_Graphics::LineStyle m_lineStyle;
409 	bool            m_linePropsDirty;
410 	bool                    m_bIsSymbol;
411 	bool                    m_bIsDingbat;
412 	UT_sint32               m_iPrevX1;
413 	UT_sint32               m_iPrevX2;
414 	UT_sint32               m_iPrevY1;
415 	UT_sint32               m_iPrevY2;
416 	UT_uint32               m_iPrevRect;
417 	UT_sint32               m_iXORCount;
418 
419 	/** init the cairo context once created */
420 	void _initCairo();
421 
422 	// Double buffering implementation
423 	void _DeviceContext_SwitchToBuffer();
424 	void _DeviceContext_SwitchToScreen();
425 
426 	// Suspend / resume drawing
427 	void _DeviceContext_SuspendDrawing();
428 	void _DeviceContext_ResumeDrawing();
429 
430 	// save / restore rectangle vectors
431 	std::vector<UT_Rect*> m_vSaveRect;
432 	std::vector<cairo_surface_t*> m_vSaveRectBuf;
433 
434 private:
435 	static UT_uint32 s_iInstanceCount;
436 	static UT_VersionInfo s_Version;
437 	static int s_iMaxScript;
438 	/** common private init for pango called from the constructor */
439 	void _initPango();
440 };
441 
442 
443 #endif
444