1{-# LANGUAGE CPP #-}
2{-# OPTIONS_HADDOCK hide #-}
3-- -*-haskell-*-
4--  GIMP Toolkit (GTK) - pango non-GObject types PangoTypes
5--
6--  Author : Axel Simon
7--
8--  Created: 9 Feburary 2003
9--
10--  Copyright (C) 1999-2005 Axel Simon
11--
12--  This library is free software; you can redistribute it and/or
13--  modify it under the terms of the GNU Lesser General Public
14--  License as published by the Free Software Foundation; either
15--  version 2.1 of the License, or (at your option) any later version.
16--
17--  This library is distributed in the hope that it will be useful,
18--  but WITHOUT ANY WARRANTY; without even the implied warranty of
19--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20--  Lesser General Public License for more details.
21--
22-- #hide
23
24-- |
25-- Maintainer  : gtk2hs-users@lists.sourceforge.net
26-- Stability   : provisional
27-- Portability : portable (depends on GHC)
28--
29-- Define types used in Pango which are not derived from GObject.
30--
31module Graphics.Rendering.Pango.BasicTypes (
32  GInt,
33
34  Language(Language),
35  emptyLanguage,
36  languageFromString,
37
38  FontStyle(..),
39  Weight(..),
40  Variant(..),
41  Stretch(..),
42  Underline(..),
43#if PANGO_VERSION_CHECK(1,16,0)
44  PangoGravity(..),
45  PangoGravityHint(..),
46#endif
47  PangoString(PangoString),
48  makeNewPangoString,
49  withPangoString,
50
51  PangoItem(PangoItem),
52  PangoItemRaw(PangoItemRaw),
53  makeNewPangoItemRaw,
54  withPangoItemRaw,
55
56  GlyphItem(GlyphItem),
57  GlyphStringRaw(GlyphStringRaw),
58  makeNewGlyphStringRaw,
59
60  PangoLayout(PangoLayout),
61
62  LayoutIter(LayoutIter),
63  LayoutIterRaw(LayoutIterRaw),
64  makeNewLayoutIterRaw,
65
66  LayoutLine(LayoutLine),
67  LayoutLineRaw(LayoutLineRaw),
68  makeNewLayoutLineRaw,
69  FontDescription(FontDescription),
70  makeNewFontDescription,
71
72  PangoAttrList,
73  CPangoAttribute,
74  ) where
75
76import Control.Monad (liftM)
77import Data.IORef ( IORef )
78import qualified Data.Text as T (unpack)
79import System.Glib.FFI
80import System.Glib.UTFString
81{#import Graphics.Rendering.Pango.Types#} (Font, PangoLayoutRaw)
82-- {#import Graphics.Rendering.Pango.Enums#}
83
84{# context lib="pango" prefix="pango" #}
85
86-- | An RFC-3066 language designator to choose scripts.
87--
88{#pointer* Language newtype#} deriving Eq
89
90-- | Define the gint that c2hs is the Haskell type.
91type GInt = {#type gint#}
92
93instance Show Language where
94  show (Language ptr)
95    | ptr==nullPtr = ""
96    | otherwise = T.unpack . unsafePerformIO $ peekUTFString (castPtr ptr)
97
98-- | Specifying no particular language.
99emptyLanguage :: Language
100emptyLanguage = Language nullPtr
101
102-- | Take a RFC-3066 format language tag as a string and convert it to a
103--  'Language' type that can be efficiently passed around and compared with
104--  other language tags.
105--
106-- * This function first canonicalizes the string by converting it to
107--   lowercase, mapping \'_\' to \'-\', and stripping all characters
108--   other than letters and \'-\'.
109--
110languageFromString :: GlibString string => string -> IO Language
111languageFromString language = liftM Language $
112  withUTFString language {#call language_from_string#}
113
114-- | The style of a font.
115--
116-- * 'StyleOblique' is a slanted font like 'StyleItalic',
117--   but in a roman style.
118--
119{#enum Style as FontStyle {underscoreToCase} deriving (Eq)#}
120
121instance Show FontStyle where
122  showsPrec _ StyleNormal          = shows "normal"
123  showsPrec _ StyleOblique         = shows "oblique"
124  showsPrec _ StyleItalic          = shows "italic"
125
126-- | Define attributes for 'Weight'.
127--
128{#enum Weight {underscoreToCase} deriving (Eq)#}
129
130instance Show Weight where
131  showsPrec _ WeightUltralight  = shows "ultralight"
132  showsPrec _ WeightLight       = shows "light"
133  showsPrec _ WeightNormal      = shows "normal"
134  showsPrec _ WeightSemibold    = shows "semibold"
135  showsPrec _ WeightBold        = shows "bold"
136  showsPrec _ WeightUltrabold   = shows "ultrabold"
137  showsPrec _ WeightHeavy       = shows "heavy"
138#if PANGO_VERSION_CHECK(1,24,0)
139  showsPrec _ WeightThin        = shows "thin"
140  showsPrec _ WeightBook        = shows "book"
141  showsPrec _ WeightMedium      = shows "medium"
142  showsPrec _ WeightUltraheavy  = shows "ultraheavy"
143#endif
144
145-- | The variant of a font.
146--
147-- * The 'VariantSmallCaps' is a version of a font where lower case
148--   letters are shown as physically smaller upper case letters.
149--
150{#enum Variant {underscoreToCase} deriving (Eq)#}
151
152instance Show Variant where
153  showsPrec _ VariantNormal       = shows "normal"
154  showsPrec _ VariantSmallCaps    = shows "smallcaps"
155
156-- | Define how wide characters are.
157--
158{#enum Stretch {underscoreToCase} deriving (Eq)#}
159
160instance Show Stretch where
161  showsPrec _ StretchUltraCondensed     = shows "ultracondensed"
162  showsPrec _ StretchExtraCondensed     = shows "extracondensed"
163  showsPrec _ StretchCondensed          = shows "condensed"
164  showsPrec _ StretchSemiCondensed      = shows "semicondensed"
165  showsPrec _ StretchNormal             = shows "normal"
166  showsPrec _ StretchSemiExpanded       = shows "semiexpanded"
167  showsPrec _ StretchExpanded           = shows "expanded"
168  showsPrec _ StretchExtraExpanded      = shows "extraexpanded"
169  showsPrec _ StretchUltraExpanded      = shows "ultraexpanded"
170
171-- | Define attributes for 'Underline'.
172--
173-- * The squiggly underline for errors is only available in Gtk 2.4 and higher.
174--
175{#enum Underline {underscoreToCase} deriving (Eq)#}
176
177instance Show Underline where
178  showsPrec _ UnderlineNone     = shows "none"
179  showsPrec _ UnderlineSingle   = shows "single"
180  showsPrec _ UnderlineDouble   = shows "double"
181  showsPrec _ UnderlineLow      = shows "low"
182  showsPrec _ UnderlineError    = shows "error"
183
184#if PANGO_VERSION_CHECK(1,16,0)
185-- |  The 'PangoGravity' type represents the orientation of glyphs in a
186-- segment of text. The value 'GravitySouth', for instance, indicates that the
187-- text stands upright, i.e. that the base of the letter is directed
188-- downwards.
189--
190-- This is useful when rendering vertical text layouts. In those situations,
191-- the layout is rotated using a non-identity 'PangoMatrix', and then glyph
192-- orientation is controlled using 'PangoGravity'. Not every value in this
193-- enumeration makes sense for every usage of 'Gravity'; for example,
194-- 'PangoGravityAuto' only can be passed to 'pangoContextSetBaseGravity' and
195-- can only be returned by 'pangoContextGetBaseGravity'.
196--
197-- * See also: 'PangoGravityHint'
198--
199-- * Gravity is resolved from the context matrix.
200--
201-- * Since Pango 1.16
202--
203{#enum PangoGravity {underscoreToCase} with prefix="" deriving (Eq)#}
204
205instance Show PangoGravity where
206  show PangoGravitySouth = "south"
207  show PangoGravityEast = "east"
208  show PangoGravityNorth = "north"
209  show PangoGravityWest = "west"
210  show PangoGravityAuto = "auto"
211
212-- | The 'PangoGravityHint' defines how horizontal scripts should behave in a
213-- vertical context.
214--
215-- * 'PangoGravityHintNatural': scripts will take their natural gravity based
216--   on the base gravity and the script. This is the default.
217--
218-- * 'PangoGravityHintStrong': always use the base gravity set, regardless of
219--   the script.
220--
221-- * 'PangoGravityHintLine': for scripts not in their natural direction (eg.
222--   Latin in East gravity), choose per-script gravity such that every script
223--   respects the line progression. This means, Latin and Arabic will take
224--   opposite gravities and both flow top-to-bottom for example.
225--
226{#enum PangoGravityHint {underscoreToCase} with prefix="" deriving (Eq)#}
227
228instance Show PangoGravityHint where
229  show PangoGravityHintNatural = "natural"
230  show PangoGravityHintStrong = "strong"
231  show PangoGravityHintLine = "line"
232
233#endif
234
235-- A string that is stored with each GlyphString, PangoItem
236data PangoString = PangoString UTFCorrection CInt (ForeignPtr CChar)
237
238makeNewPangoString :: GlibString string => string -> IO PangoString
239makeNewPangoString str = do
240  let correct = genUTFOfs str
241  (strPtr, len) <- newUTFStringLen str
242  let cLen = fromIntegral len
243  liftM (PangoString correct cLen) $ newForeignPtr strPtr finalizerFree
244
245withPangoString :: PangoString ->
246                   (UTFCorrection -> CInt -> Ptr CChar -> IO a) -> IO a
247withPangoString (PangoString c l ptr) act = withForeignPtr ptr $ \strPtr ->
248  act c l strPtr
249
250-- paired with PangoString to create a Haskell GlyphString
251{#pointer *PangoGlyphString as GlyphStringRaw foreign newtype #}
252
253makeNewGlyphStringRaw :: Ptr GlyphStringRaw -> IO GlyphStringRaw
254makeNewGlyphStringRaw llPtr = do
255  liftM GlyphStringRaw $ newForeignPtr llPtr pango_glyph_string_free
256
257foreign import ccall unsafe "&pango_glyph_string_free"
258  pango_glyph_string_free :: FinalizerPtr GlyphStringRaw
259
260-- paired with PangoString and UTFCorrection to create a Haskell PangoItem
261{#pointer *PangoItem as PangoItemRaw foreign newtype #}
262
263makeNewPangoItemRaw :: Ptr PangoItemRaw -> IO PangoItemRaw
264makeNewPangoItemRaw llPtr = do
265  liftM PangoItemRaw $ newForeignPtr llPtr pango_item_free
266
267withPangoItemRaw :: PangoItemRaw -> (Ptr PangoItemRaw -> IO a) -> IO a
268withPangoItemRaw (PangoItemRaw pir) act = withForeignPtr pir act
269
270foreign import ccall unsafe "&pango_item_free"
271  pango_item_free :: FinalizerPtr PangoItemRaw
272
273#if PANGO_VERSION_CHECK(1,2,0)
274{#pointer *PangoGlyphItem as GlyphItemRaw #}
275#endif
276
277-- With each GlyphString we pair a UTFCorrection
278-- and the marshalled UTF8 string. Together, this data
279-- enables us to bind all functions that take or return
280-- indices into the CString, rather then unicode position. Note that text
281-- handling is particularly horrible with UTF8: Several UTF8 bytes can make
282-- up one Unicode character (a Haskell Char), and several Unicode characters
283-- can form a cluster (e.g. a letter and an accent). We protect the user from
284-- UTF8\/Haskell String conversions, but not from clusters.
285
286-- | A sequence of characters that are rendered with the same settings.
287--
288-- * A preprocessing stage done by 'itemize' splits the input text into
289--   several chunks such that each chunk can be rendered with the same
290--   font, direction, slant, etc. Some attributes such as the color,
291--   underline or strikethrough do not affect a break into several
292--   'PangoItem's. See also 'GlyphItem'.
293--
294data PangoItem = PangoItem PangoString PangoItemRaw
295
296-- | A sequence of glyphs for a chunk of a string.
297--
298-- * A glyph item contains the graphical representation of a 'PangoItem'.
299--   Clusters (like @e@ and an accent modifier) as well as legatures
300--   (such as @ffi@ turning into a single letter that omits the dot over the
301--   @i@) are usually represented as a single glyph.
302--
303data GlyphItem = GlyphItem PangoItem GlyphStringRaw
304
305-- | A rendered paragraph.
306data PangoLayout = PangoLayout (IORef PangoString) PangoLayoutRaw
307
308-- | An iterator to examine a layout.
309--
310data LayoutIter = LayoutIter (IORef PangoString) LayoutIterRaw
311
312{#pointer *PangoLayoutIter as LayoutIterRaw foreign newtype #}
313
314makeNewLayoutIterRaw :: Ptr LayoutIterRaw -> IO LayoutIterRaw
315makeNewLayoutIterRaw liPtr =
316  liftM LayoutIterRaw $ newForeignPtr liPtr layout_iter_free
317
318foreign import ccall unsafe "&pango_layout_iter_free"
319  layout_iter_free :: FinalizerPtr LayoutIterRaw
320
321-- | A single line in a 'PangoLayout'.
322--
323data LayoutLine = LayoutLine (IORef PangoString) LayoutLineRaw
324
325{#pointer *PangoLayoutLine as LayoutLineRaw foreign newtype #}
326
327makeNewLayoutLineRaw :: Ptr LayoutLineRaw -> IO LayoutLineRaw
328makeNewLayoutLineRaw llPtr = do
329  liftM LayoutLineRaw $ newForeignPtr llPtr pango_layout_line_unref
330
331foreign import ccall unsafe "&pango_layout_line_unref"
332  pango_layout_line_unref :: FinalizerPtr LayoutLineRaw
333
334-- | A possibly partial description of font(s).
335--
336{#pointer *PangoFontDescription as FontDescription foreign newtype #}
337
338makeNewFontDescription :: Ptr FontDescription -> IO FontDescription
339makeNewFontDescription llPtr = do
340  liftM FontDescription $ newForeignPtr llPtr pango_font_description_free
341
342foreign import ccall unsafe "&pango_font_description_free"
343  pango_font_description_free :: FinalizerPtr FontDescription
344
345-- Attributes
346{#pointer *PangoAttrList #}
347
348{#pointer *PangoAttribute as CPangoAttribute#}
349
350-- dirty hack to make PangoAttribute showable
351instance Show FontDescription where
352  show fd = unsafePerformIO $ do
353    strPtr <- {#call unsafe font_description_to_string#} fd
354    str <- peekUTFString strPtr
355    {#call unsafe g_free#} (castPtr strPtr)
356    return $ T.unpack str
357
358
359