cd_text.e 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. deferred class CD_TEXT
  2. -- A raster text using a font with styles. The position the text is drawn
  3. -- depends on the text alignment attribute.
  4. --
  5. -- The library has at least 4 standard typefaces: "System" (which depends on
  6. -- the driver and platform), "Courier" (mono spaced with serif), "Times"
  7. -- (proportional with serif) and "Helvetica" (proportional without serif). Each
  8. -- typeface can have some styles: Plain, Bold, Italic and a combination of Bold
  9. -- and Italic. As an alternative to the standard typefaces, you can use other
  10. -- typefaces or native driver typefaces with the function "set_native_font", but
  11. -- they may work in a reduced set of drivers.
  12. --
  13. -- You may retrieve the dimensions of the selected font with function
  14. -- "get_font_dim". Also you may retrieve the bounding box of a specific text
  15. -- before drawing by using the "get_text_size" and "get_text_box" functions.
  16. --
  17. -- The text is drawn using a reference point; you can change the alignment
  18. -- relative to this point using the "set_text_aligment" function.
  19. inherit
  20. CANVAS_DRAW
  21. feature {ANY}
  22. -- Operations
  23. draws_text (x, y: INTEGER; text: STRING)
  24. -- Draws a text in the position (x,y) according to the current font and
  25. -- text alignment. It expects an ANSI string. Can have line breaks.
  26. do
  27. int_canvas_text (cnvs, x, y, get_pointer(text.to_c))
  28. end
  29. draws_text_real (x, y: REAL_64; text: STRING)
  30. -- Like "draws_text" but with real coordinates.
  31. do
  32. int_canvas_c_double_text (cnvs, x, y, get_pointer(text.to_c))
  33. end
  34. wd_draws_text (x, y: REAL_64; text: STRING)
  35. -- Like "draws_text" but with World coordinates.
  36. do
  37. int_wd_canvas_text (cnvs, x, y, get_pointer(text.to_c))
  38. end
  39. -- Attributes
  40. set_font_typeface (typeface: STRING)
  41. -- The font type can be one of the standard type faces or other driver
  42. -- dependent type face. Since font face names are not a standard between
  43. -- drivers, a few names are specially handled to improve application
  44. -- portability. If you want to use names that work for all systems we
  45. -- recommend using: "Courier", "Times" and "Helvetica".
  46. -- Default: System.
  47. do
  48. int_canvas_font(cnvs, get_pointer(typeface.to_c), -1, 0)
  49. end
  50. get_font_typeface: STRING
  51. local
  52. t, s, z: POINTER
  53. str: STRING
  54. do
  55. int_canvas_get_font (cnvs, t, s, z)
  56. create str.make_from_c(t)
  57. Result := str
  58. end
  59. set_font_styles (styles: INTEGER)
  60. -- Defines the style of the font. Can be a combination of:
  61. --
  62. -- 0 = Plain
  63. -- 1 = Bold
  64. -- 2 = Italic
  65. -- 4 = Underline
  66. -- 8 = Strikeout
  67. --
  68. -- Only the Windows and PDF drivers support underline and strikeout.
  69. -- For example to define Bold and Italic, use 1|2 (bitwise logical
  70. -- inclusive). Default: 0 (Plain).
  71. local
  72. p: POINTER
  73. do
  74. int_canvas_font(cnvs, p, styles, 0)
  75. end
  76. get_font_styles: INTEGER
  77. local
  78. p, si: POINTER
  79. s: INTEGER
  80. do
  81. int_canvas_get_font (cnvs, p, $s, si)
  82. Result := s
  83. end
  84. set_font_size (size: INTEGER)
  85. -- The size is provided in points (1/72 inch) or in pixels (using negative
  86. -- values).
  87. -- Default: 12.
  88. local
  89. p: POINTER
  90. do
  91. int_canvas_font(cnvs, p, -1, size)
  92. end
  93. get_font_size: INTEGER
  94. local
  95. p, st: POINTER
  96. s: INTEGER
  97. do
  98. int_canvas_get_font (cnvs, p, st, $s)
  99. Result := s
  100. end
  101. set_wd_font_size (size: REAL_64)
  102. -- Size is specified in millimeters, but is internally converted
  103. -- to points.
  104. local
  105. p: POINTER
  106. do
  107. int_wd_canvas_font(cnvs, p, -1, size)
  108. end
  109. get_wd_font_styles: REAL_64
  110. local
  111. p, st: POINTER
  112. s: REAL_64
  113. do
  114. int_wd_canvas_get_font (cnvs, p, st, $s)
  115. Result := s
  116. end
  117. set_native_font (format: STRING)
  118. local
  119. p: POINTER
  120. do
  121. p := int_canvas_native_font(cnvs, get_pointer(format.to_c))
  122. end
  123. get_previous_native_font: STRING
  124. -- Selects a font based on a string description. The description can
  125. -- depend on the driver and the platform, but a common definition is
  126. -- available for all drivers. It does not need to be stored by the
  127. -- application, as it is internally replicated by the library. The string
  128. -- is case sensitive.
  129. --
  130. -- The common format definition is similar to the the Pango library
  131. -- Font Description, used by GTK+2. It is defined as having 3 parts:
  132. -- <font family>, <font styles> <font size>. For ex: "Times, Bold 18",
  133. -- or "Arial,Helvetica, Italic Underline -24". The supported styles
  134. -- include: Bold, Italic, Underline and Strikeout. Underline,
  135. -- Strikeout, and negative pixel values are not supported by the
  136. -- standard Pango Font Description. The Pango format include many
  137. -- other definitions not supported by the CD format, they are just
  138. -- ignored.
  139. --
  140. -- The IUP "FONT" attribute internal formats are also accepted in all
  141. -- drivers and platforms.
  142. local
  143. p, s: POINTER
  144. str: STRING
  145. do
  146. s := int_canvas_native_font (cnvs, p)
  147. create str.make_from_c(s)
  148. Result := str
  149. end
  150. get_current_native_font: STRING
  151. local
  152. p: POINTER
  153. v, str: STRING
  154. do
  155. v := "(char*)CD_QUERY"
  156. p := int_canvas_native_font (cnvs, get_pointer(v.to_c))
  157. create str.make_from_c(p)
  158. Result := str
  159. end
  160. set_text_alignment (value: STRING)
  161. -- Defines the vertical and horizontal alignment of a text
  162. require
  163. is_valid_alignment(value)
  164. local
  165. v: INTEGER
  166. do
  167. v := int_canvas_text_alignment(cnvs, alignment_to_int(value))
  168. end
  169. get_text_alignment: STRING
  170. local
  171. i: INTEGER
  172. do
  173. i := int_canvas_text_alignment(cnvs, -1)
  174. Result := int_to_alignment(i)
  175. end
  176. set_text_orientation (angle: REAL_64)
  177. -- Defines the text orientation, which is an angle provided in degrees
  178. -- relative to the horizontal line according to which the text is
  179. -- drawn. Default: 0.
  180. local
  181. i: REAL_64
  182. do
  183. i := int_canvas_text_orientation(cnvs, angle)
  184. end
  185. get_text_orientation: REAL_64
  186. do
  187. Result := int_canvas_text_orientation(cnvs, -1)
  188. end
  189. -- Properties
  190. get_font_dim: TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
  191. -- Returns (in this order) the maximum width of a character, the
  192. -- line's height, the ascent and descent of the characters of the
  193. -- currently selected font. The line's height is the sum of the ascent
  194. -- and descent of a given additional space (if this is the case).
  195. -- All values are given in pixels and are positive.
  196. local
  197. max_width, height, ascent, descent: INTEGER
  198. do
  199. int_canvas_get_font_dim(cnvs, $max_width, $height, $ascent, $descent)
  200. Result := [max_width, height, ascent, descent]
  201. end
  202. get_wd_font_dim: TUPLE[REAL_64, REAL_64, REAL_64, REAL_64]
  203. -- Returns (in this order) the maximum width of a character, the
  204. -- line's height, the ascent and descent of the characters of the
  205. -- currently selected font. The line's height is the sum of the ascent
  206. -- and descent of a given additional space (if this is the case).
  207. -- All values are given in millimeters and are positive.
  208. local
  209. max_width, height, ascent, descent: REAL_64
  210. do
  211. int_wd_canvas_get_font_dim(cnvs, $max_width, $height, $ascent, $descent)
  212. Result := [max_width, height, ascent, descent]
  213. end
  214. get_text_size (text: STRING): TUPLE[INTEGER, INTEGER]
  215. -- Returns the text size independent from orientation.
  216. local
  217. w, h: INTEGER
  218. do
  219. int_canvas_get_text_size(cnvs, get_pointer(text.to_c), $w, $h)
  220. Result := [w, h]
  221. end
  222. get_wd_text_size (text: STRING): TUPLE[REAL_64, REAL_64]
  223. -- Returns the text size, in millimeters, independent from orientation.
  224. local
  225. w, h: REAL_64
  226. do
  227. int_wd_canvas_get_text_size(cnvs, get_pointer(text.to_c), $w, $h)
  228. Result := [w, h]
  229. end
  230. get_text_bounds (x, y: INTEGER; text: STRING): TUPLE[INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER]
  231. -- Returns the oriented bounding rectangle occupied by a text at a given
  232. -- position. The rectangle has the same dimentions returned by feature
  233. -- get_text_size. The rectangle corners are returned in counter-clock
  234. -- wise order starting with the bottom left corner, arranged
  235. -- (x0,y0,x1,y1,x2,y2,x3,y3).
  236. local
  237. p: POINTER
  238. points: MANAGED_POINTER
  239. do
  240. int_canvas_get_text_bounds(cnvs, x, y, get_pointer(text.to_c), p)
  241. create points.make_from_pointer(p, 8)
  242. Result := [points.read_integer_32(0), points.read_integer_32(1),
  243. points.read_integer_32(2), points.read_integer_32(3),
  244. points.read_integer_32(4), points.read_integer_32(5),
  245. points.read_integer_32(6), points.read_integer_32(7)]
  246. end
  247. get_text_bounds_real (x, y: REAL_64; text: STRING): TUPLE[REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64]
  248. -- Like 'get_text_bounds' but with REAL_64 values.
  249. local
  250. p: POINTER
  251. points: MANAGED_POINTER
  252. do
  253. int_canvas_c_double_get_text_bounds(cnvs, x, y, get_pointer(text.to_c), p)
  254. create points.make_from_pointer(p, 8)
  255. Result := [points.read_real_64(0), points.read_real_64(1),
  256. points.read_real_64(2), points.read_real_64(3),
  257. points.read_real_64(4), points.read_real_64(5),
  258. points.read_real_64(6), points.read_real_64(7)]
  259. end
  260. get_wd_text_bounds (x, y: REAL_64; text: STRING): TUPLE[REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64, REAL_64]
  261. -- Like 'get_text_bounds' but using World Coordinates.
  262. local
  263. p: POINTER
  264. points: MANAGED_POINTER
  265. do
  266. int_wd_canvas_get_text_bounds(cnvs, x, y, get_pointer(text.to_c), p)
  267. create points.make_from_pointer(p, 8)
  268. Result := [points.read_real_64(0), points.read_real_64(1),
  269. points.read_real_64(2), points.read_real_64(3),
  270. points.read_real_64(4), points.read_real_64(5),
  271. points.read_real_64(6), points.read_real_64(7)]
  272. end
  273. get_text_box (x, y: INTEGER; text: STRING): TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]
  274. -- Returns the horizontal bounding rectangle occupied by a text at a
  275. -- given position. If orientation is not 0 then its area is always larger
  276. -- than the area of the rectangle returned by 'get_text_bounds'.
  277. local
  278. xmin, xmax, ymin, ymax: INTEGER
  279. do
  280. int_canvas_get_text_box(cnvs, x, y, get_pointer(text.to_c), $xmin, $xmax, $ymin, $ymax)
  281. Result := [xmin, xmax, ymin, ymax]
  282. end
  283. get_text_box_real (x, y: REAL_64; text: STRING): TUPLE[REAL_64, REAL_64, REAL_64, REAL_64]
  284. -- Like 'get_text_box' but using REAL_64 values.
  285. local
  286. xmin, xmax, ymin, ymax: REAL_64
  287. do
  288. int_canvas_c_double_get_text_box(cnvs, x, y, get_pointer(text.to_c), $xmin, $xmax, $ymin, $ymax)
  289. Result := [xmin, xmax, ymin, ymax]
  290. end
  291. get_wd_text_box (x, y: REAL_64; text: STRING): TUPLE[REAL_64, REAL_64, REAL_64, REAL_64]
  292. -- Like 'get_text_box' but using World Coordinates.
  293. local
  294. xmin, xmax, ymin, ymax: REAL_64
  295. do
  296. int_wd_canvas_get_text_box(cnvs, x, y, get_pointer(text.to_c), $xmin, $xmax, $ymin, $ymax)
  297. Result := [xmin, xmax, ymin, ymax]
  298. end
  299. -- Validations
  300. is_valid_style (style: STRING): BOOLEAN
  301. do
  302. if style.is_equal("CD_PLAIN") or
  303. style.is_equal("CD_BOLD") or
  304. style.is_equal("CD_ITALIC") or
  305. style.is_equal("CD_UNDERLINE") or
  306. style.is_equal("CD_STRIKEOUT") then
  307. Result := True
  308. else
  309. Result := False
  310. end
  311. end
  312. is_valid_alignment (value: STRING): BOOLEAN
  313. do
  314. if value.is_equal("CD_NORTH") or
  315. value.is_equal("CD_SOUTH") or
  316. value.is_equal("CD_EAST") or
  317. value.is_equal("CD_WEST") or
  318. value.is_equal("CD_NORTH_EAST") or
  319. value.is_equal("CD_NORTH_WEST") or
  320. value.is_equal("CD_SOUTH_EAST") or
  321. value.is_equal("CD_SOUTH_WEST") or
  322. value.is_equal("CD_CENTER") or
  323. value.is_equal("CD_BASE_LEFT") or
  324. value.is_equal("CD_BASE_CENTER") or
  325. value.is_equal("CD_BASE_RIGHT") then
  326. Result := True
  327. else
  328. Result := False
  329. end
  330. end
  331. feature {NONE}
  332. -- Convert
  333. styles_to_int (styles: ARRAY[STRING]): INTEGER
  334. local
  335. i, x: INTEGER
  336. style: STRING
  337. do
  338. i := 0
  339. from
  340. x := 0
  341. invariant
  342. valid_style: is_valid_style (styles.item(x))
  343. until
  344. x = styles.count
  345. loop
  346. style := styles.item(x)
  347. if style.is_equal("CD_PLAIN") then
  348. i := i | 0
  349. elseif style.is_equal("CD_BOLD") then
  350. i := i | 1
  351. elseif style.is_equal("CD_ITALIC") then
  352. i := i | 2
  353. elseif style.is_equal("CD_UNDERLINE") then
  354. i := i | 4
  355. elseif style.is_equal("CD_STRIKEOUT") then
  356. i := i | 8
  357. end
  358. x := x + 1
  359. end
  360. Result := i
  361. end
  362. alignment_to_int (value: STRING): INTEGER
  363. do
  364. if value.is_equal("CD_NORTH") then
  365. Result := 0
  366. elseif value.is_equal("CD_SOUTH") then
  367. Result := 1
  368. elseif value.is_equal("CD_EAST") then
  369. Result := 2
  370. elseif value.is_equal("CD_WEST") then
  371. Result := 3
  372. elseif value.is_equal("CD_NORTH_EAST") then
  373. Result := 4
  374. elseif value.is_equal("CD_NORTH_WEST") then
  375. Result := 5
  376. elseif value.is_equal("CD_SOUTH_EAST") then
  377. Result := 6
  378. elseif value.is_equal("CD_SOUTH_WEST") then
  379. Result := 7
  380. elseif value.is_equal("CD_CENTER") then
  381. Result := 8
  382. elseif value.is_equal("CD_BASE_LEFT") then
  383. Result := 9
  384. elseif value.is_equal("CD_BASE_CENTER") then
  385. Result := 10
  386. elseif value.is_equal("CD_BASE_RIGHT") then
  387. Result := 11
  388. end
  389. end
  390. int_to_alignment (value: INTEGER): STRING
  391. do
  392. if value.is_equal(0) then
  393. Result := "CD_NORTH"
  394. elseif value.is_equal(1) then
  395. Result := "CD_SOUTH"
  396. elseif value.is_equal(2) then
  397. Result := "CD_EAST"
  398. elseif value.is_equal(3) then
  399. Result := "CD_WEST"
  400. elseif value.is_equal(4) then
  401. Result := "CD_NORTH_EAST"
  402. elseif value.is_equal(5) then
  403. Result := "CD_NORTH_WEST"
  404. elseif value.is_equal(6) then
  405. Result := "CD_SOUTH_EAST"
  406. elseif value.is_equal(7) then
  407. Result := "CD_SOUTH_WEST"
  408. elseif value.is_equal(8) then
  409. Result := "CD_CENTER"
  410. elseif value.is_equal(9) then
  411. Result := "CD_BASE_LEFT"
  412. elseif value.is_equal(10) then
  413. Result := "CD_BASE_CENTER"
  414. elseif value.is_equal(11) then
  415. Result := "CD_BASE_RIGHT"
  416. else
  417. Result := "CD_NORTH"
  418. end
  419. end
  420. -- Internals
  421. int_canvas_text (wgt: POINTER; x, y: INTEGER; text: POINTER)
  422. external
  423. "C inline use %"eiffel-iup.h%""
  424. alias
  425. "cdCanvasText ($wgt, $x, $y, $text);"
  426. end
  427. int_canvas_c_double_text (wgt: POINTER; x, y: REAL_64; text: POINTER)
  428. external
  429. "C inline use %"eiffel-iup.h%""
  430. alias
  431. "cdfCanvasText ($wgt, $x, $y, $text);"
  432. end
  433. int_wd_canvas_text (wgt: POINTER; x, y: REAL_64; text: POINTER)
  434. external
  435. "C inline use %"eiffel-iup.h%""
  436. alias
  437. "wdCanvasText ($wgt, $x, $y, $text);"
  438. end
  439. int_canvas_font (wgt, f: POINTER; tf, fs: INTEGER)
  440. external
  441. "C inline use %"eiffel-iup.h%""
  442. alias
  443. "cdCanvasFont ($wgt, $f, $tf, $fs);"
  444. end
  445. int_wd_canvas_font (wgt, f: POINTER; tf: INTEGER; fs: REAL_64)
  446. external
  447. "C inline use %"eiffel-iup.h%""
  448. alias
  449. "wdCanvasFont ($wgt, $f, $tf, $fs);"
  450. end
  451. int_canvas_get_font (wgt, f, tf, fs: POINTER)
  452. external
  453. "C inline use %"eiffel-iup.h%""
  454. alias
  455. "cdCanvasGetFont ($wgt, $f, $tf, $fs);"
  456. end
  457. int_wd_canvas_get_font (wgt, f, tf, fs: POINTER)
  458. external
  459. "C inline use %"eiffel-iup.h%""
  460. alias
  461. "wdCanvasGetFont ($wgt, $f, $tf, $fs);"
  462. end
  463. int_canvas_native_font (wgt, sf: POINTER): POINTER
  464. external
  465. "C inline use %"eiffel-iup.h%""
  466. alias
  467. "return cdCanvasNativeFont ($wgt, $sf);"
  468. end
  469. int_canvas_text_alignment (wgt: POINTER; algn: INTEGER): INTEGER
  470. external
  471. "C inline use %"eiffel-iup.h%""
  472. alias
  473. "return cdCanvasTextAlignment ($wgt, $algn);"
  474. end
  475. int_canvas_text_orientation (wgt: POINTER; ang: REAL_64): REAL_64
  476. external
  477. "C inline use %"eiffel-iup.h%""
  478. alias
  479. "return cdCanvasTextOrientation ($wgt, $ang);"
  480. end
  481. int_canvas_get_font_dim (wgt, mw, h, a, d: POINTER)
  482. external
  483. "C inline use %"eiffel-iup.h%""
  484. alias
  485. "cdCanvasGetFontDim ($wgt, $mw, $h, $a, $d);"
  486. end
  487. int_wd_canvas_get_font_dim (wgt, mw, h, a, d: POINTER)
  488. external
  489. "C inline use %"eiffel-iup.h%""
  490. alias
  491. "wdCanvasGetFontDim ($wgt, $mw, $h, $a, $d);"
  492. end
  493. int_canvas_get_text_size (wgt, text, w, h: POINTER)
  494. external
  495. "C inline use %"eiffel-iup.h%""
  496. alias
  497. "cdCanvasGetTextSize ($wgt, $text, $w, $h);"
  498. end
  499. int_wd_canvas_get_text_size (wgt, text, w, h: POINTER)
  500. external
  501. "C inline use %"eiffel-iup.h%""
  502. alias
  503. "wdCanvasGetTextSize ($wgt, $text, $w, $h);"
  504. end
  505. int_canvas_get_text_bounds (wgt: POINTER; x, y: INTEGER; text, r: POINTER)
  506. external
  507. "C inline use %"eiffel-iup.h%""
  508. alias
  509. "cdCanvasGetTextBounds ($wgt, $x, $y, $text, $r);"
  510. end
  511. int_canvas_c_double_get_text_bounds (wgt: POINTER; x, y: REAL_64; text, r: POINTER)
  512. external
  513. "C inline use %"eiffel-iup.h%""
  514. alias
  515. "cdfCanvasGetTextBounds ($wgt, $x, $y, $text, $r);"
  516. end
  517. int_wd_canvas_get_text_bounds (wgt: POINTER; x, y: REAL_64; text, r: POINTER)
  518. external
  519. "C inline use %"eiffel-iup.h%""
  520. alias
  521. "wdCanvasGetTextBounds ($wgt, $x, $y, $text, $r);"
  522. end
  523. int_canvas_get_text_box (wgt: POINTER; x, y: INTEGER; text, xmin, xmax, ymin, ymax: POINTER)
  524. external
  525. "C inline use %"eiffel-iup.h%""
  526. alias
  527. "cdCanvasGetTextBox ($wgt, $x, $y, $text, $xmin, $xmax, $ymin, $ymax);"
  528. end
  529. int_canvas_c_double_get_text_box (wgt: POINTER; x, y: REAL_64; text, xmin, xmax, ymin, ymax: POINTER)
  530. external
  531. "C inline use %"eiffel-iup.h%""
  532. alias
  533. "cdfCanvasGetTextBox ($wgt, $x, $y, $text, $xmin, $xmax, $ymin, $ymax);"
  534. end
  535. int_wd_canvas_get_text_box (wgt: POINTER; x, y: REAL_64; text, xmin, xmax, ymin, ymax: POINTER)
  536. external
  537. "C inline use %"eiffel-iup.h%""
  538. alias
  539. "wdCanvasGetTextBox ($wgt, $x, $y, $text, $xmin, $xmax, $ymin, $ymax);"
  540. end
  541. end
  542. -- The MIT License (MIT)
  543. -- Copyright (c) 2017, 2019 by German A. Arias
  544. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  545. -- of this software and associated documentation files (the "Software"), to deal
  546. -- in the Software without restriction, including without limitation the rights
  547. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  548. -- copies of the Software, and to permit persons to whom the Software is
  549. -- furnished to do so, subject to the following conditions:
  550. --
  551. -- The above copyright notice and this permission notice shall be included in
  552. -- all copies or substantial portions of the Software.
  553. --
  554. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  555. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  556. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  557. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  558. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  559. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  560. -- SOFTWARE.