dynamicTextFont.I 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. // Filename: dynamicTextFont.I
  2. // Created by: drose (08Feb02)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. ////////////////////////////////////////////////////////////////////
  15. // Function: DynamicTextFont::get_name
  16. // Access: Published
  17. // Description: Disambiguates the get_name() method between that
  18. // inherited from TextFont and that inherited from
  19. // FreetypeFont.
  20. ////////////////////////////////////////////////////////////////////
  21. INLINE const string &DynamicTextFont::
  22. get_name() const {
  23. return TextFont::get_name();
  24. }
  25. ////////////////////////////////////////////////////////////////////
  26. // Function: DynamicTextFont::set_point_size
  27. // Access: Published
  28. // Description: Sets the point size of the font. This controls the
  29. // apparent size of the font onscreen. By convention, a
  30. // 10 point font is about 1 screen unit high.
  31. //
  32. // This should only be called before any characters have
  33. // been requested out of the font, or immediately after
  34. // calling clear().
  35. ////////////////////////////////////////////////////////////////////
  36. INLINE bool DynamicTextFont::
  37. set_point_size(float point_size) {
  38. // If this assertion fails, you didn't call clear() first. RTFM.
  39. nassertr(get_num_pages() == 0, false);
  40. return FreetypeFont::set_point_size(point_size);
  41. }
  42. ////////////////////////////////////////////////////////////////////
  43. // Function: DynamicTextFont::get_point_size
  44. // Access: Published
  45. // Description: Returns the point size of the font.
  46. ////////////////////////////////////////////////////////////////////
  47. INLINE float DynamicTextFont::
  48. get_point_size() const {
  49. return FreetypeFont::get_point_size();
  50. }
  51. ////////////////////////////////////////////////////////////////////
  52. // Function: DynamicTextFont::set_pixels_per_unit
  53. // Access: Published
  54. // Description: Set the resolution of the texture map, and hence the
  55. // clarity of the resulting font. This sets the number
  56. // of pixels in the texture map that are used for each
  57. // onscreen unit.
  58. //
  59. // Setting this number larger results in an easier to
  60. // read font, but at the cost of more texture memory.
  61. //
  62. // This should only be called before any characters have
  63. // been requested out of the font, or immediately after
  64. // calling clear().
  65. ////////////////////////////////////////////////////////////////////
  66. INLINE bool DynamicTextFont::
  67. set_pixels_per_unit(float pixels_per_unit) {
  68. // If this assertion fails, you didn't call clear() first. RTFM.
  69. nassertr(get_num_pages() == 0, false);
  70. return FreetypeFont::set_pixels_per_unit(pixels_per_unit);
  71. }
  72. ////////////////////////////////////////////////////////////////////
  73. // Function: DynamicTextFont::get_pixels_per_unit
  74. // Access: Published
  75. // Description: Returns the resolution of the texture map. See
  76. // set_pixels_per_unit().
  77. ////////////////////////////////////////////////////////////////////
  78. INLINE float DynamicTextFont::
  79. get_pixels_per_unit() const {
  80. return FreetypeFont::get_pixels_per_unit();
  81. }
  82. ////////////////////////////////////////////////////////////////////
  83. // Function: DynamicTextFont::set_scale_factor
  84. // Access: Published
  85. // Description: Sets the factor by which the font is rendered larger
  86. // by the FreeType library before being filtered down to
  87. // its actual size in the texture as specified by
  88. // set_pixels_per_unit(). This may be set to a number
  89. // larger than 1.0 to improve the font's antialiasing
  90. // (since FreeType doesn't really do a swell job of
  91. // antialiasing by itself). There is some performance
  92. // implication for setting this different than 1.0, but
  93. // it is probably small.
  94. //
  95. // This should only be called before any characters have
  96. // been requested out of the font, or immediately after
  97. // calling clear().
  98. ////////////////////////////////////////////////////////////////////
  99. INLINE bool DynamicTextFont::
  100. set_scale_factor(float scale_factor) {
  101. // If this assertion fails, you didn't call clear() first. RTFM.
  102. nassertr(get_num_pages() == 0, false);
  103. return FreetypeFont::set_scale_factor(scale_factor);
  104. }
  105. ////////////////////////////////////////////////////////////////////
  106. // Function: DynamicTextFont::get_scale_factor
  107. // Access: Published
  108. // Description: Returns the antialiasing scale factor. See
  109. // set_scale_factor().
  110. ////////////////////////////////////////////////////////////////////
  111. INLINE float DynamicTextFont::
  112. get_scale_factor() const {
  113. return FreetypeFont::get_scale_factor();
  114. }
  115. ////////////////////////////////////////////////////////////////////
  116. // Function: DynamicTextFont::set_native_antialias
  117. // Access: Published
  118. // Description: Sets whether the Freetype library's built-in
  119. // antialias mode is enabled. There are two unrelated
  120. // ways to achieve antialiasing: with Freetype's native
  121. // antialias mode, and with the use of a scale_factor
  122. // greater than one. By default, both modes are
  123. // enabled.
  124. //
  125. // At low resolutions, some fonts may do better with one
  126. // mode or the other. In general, Freetype's native
  127. // antialiasing will produce less blurry results, but
  128. // may introduce more artifacts.
  129. ////////////////////////////////////////////////////////////////////
  130. INLINE void DynamicTextFont::
  131. set_native_antialias(bool native_antialias) {
  132. // If this assertion fails, you didn't call clear() first. RTFM.
  133. nassertv(get_num_pages() == 0);
  134. FreetypeFont::set_native_antialias(native_antialias);
  135. }
  136. ////////////////////////////////////////////////////////////////////
  137. // Function: DynamicTextFont::get_native_antialias
  138. // Access: Published
  139. // Description: Returns whether Freetype's built-in antialias mode is
  140. // enabled. See set_native_antialias().
  141. ////////////////////////////////////////////////////////////////////
  142. INLINE bool DynamicTextFont::
  143. get_native_antialias() const {
  144. return FreetypeFont::get_native_antialias();
  145. }
  146. ////////////////////////////////////////////////////////////////////
  147. // Function: DynamicTextFont::get_font_pixel_size
  148. // Access: Published
  149. // Description: This is used to report whether the requested pixel
  150. // size is being only approximated by a fixed-pixel-size
  151. // font. This returns 0 in the normal case, in which a
  152. // scalable font is used, or the fixed-pixel-size font
  153. // has exactly the requested pixel size.
  154. //
  155. // If this returns non-zero, it is the pixel size of the
  156. // font that we are using to approximate our desired
  157. // size.
  158. ////////////////////////////////////////////////////////////////////
  159. INLINE int DynamicTextFont::
  160. get_font_pixel_size() const {
  161. return FreetypeFont::get_font_pixel_size();
  162. }
  163. ////////////////////////////////////////////////////////////////////
  164. // Function: DynamicTextFont::get_line_height
  165. // Access: Published
  166. // Description: Returns the number of units high each line of text
  167. // is.
  168. ////////////////////////////////////////////////////////////////////
  169. INLINE float DynamicTextFont::
  170. get_line_height() const {
  171. return TextFont::get_line_height();
  172. }
  173. ////////////////////////////////////////////////////////////////////
  174. // Function: DynamicTextFont::get_space_advance
  175. // Access: Published
  176. // Description: Returns the number of units wide a space is.
  177. ////////////////////////////////////////////////////////////////////
  178. INLINE float DynamicTextFont::
  179. get_space_advance() const {
  180. return TextFont::get_space_advance();
  181. }
  182. ////////////////////////////////////////////////////////////////////
  183. // Function: DynamicTextFont::set_texture_margin
  184. // Access: Published
  185. // Description: Sets the number of pixels of padding that is added
  186. // around the border of each glyph before adding it to
  187. // the texture map. This reduces the bleed in from
  188. // neighboring glyphs in the texture map.
  189. ////////////////////////////////////////////////////////////////////
  190. INLINE void DynamicTextFont::
  191. set_texture_margin(int texture_margin) {
  192. _texture_margin = texture_margin;
  193. }
  194. ////////////////////////////////////////////////////////////////////
  195. // Function: DynamicTextFont::get_texture_margin
  196. // Access: Published
  197. // Description: Returns the number of pixels of padding that is added
  198. // around the border of each glyph in the texture map.
  199. // See set_texture_margin().
  200. ////////////////////////////////////////////////////////////////////
  201. INLINE int DynamicTextFont::
  202. get_texture_margin() const {
  203. return _texture_margin;
  204. }
  205. ////////////////////////////////////////////////////////////////////
  206. // Function: DynamicTextFont::set_poly_margin
  207. // Access: Published
  208. // Description: Sets the number of pixels of padding that is included
  209. // around each glyph in the generated polygons. This
  210. // helps prevent the edges of the glyphs from being cut
  211. // off at small minifications. It is not related to the
  212. // amount of extra pixels reserved in the texture map
  213. // (but it should be set somewhat smaller than this
  214. // number, which is controlled by set_texture_margin(),
  215. // to prevent bleed-in from neighboring letters in the
  216. // texture).
  217. ////////////////////////////////////////////////////////////////////
  218. INLINE void DynamicTextFont::
  219. set_poly_margin(float poly_margin) {
  220. _poly_margin = poly_margin;
  221. }
  222. ////////////////////////////////////////////////////////////////////
  223. // Function: DynamicTextFont::get_poly_margin
  224. // Access: Published
  225. // Description: Returns the number of pixels of padding that is
  226. // included around each glyph in the generated polygons.
  227. // See set_poly_margin().
  228. ////////////////////////////////////////////////////////////////////
  229. INLINE float DynamicTextFont::
  230. get_poly_margin() const {
  231. return _poly_margin;
  232. }
  233. ////////////////////////////////////////////////////////////////////
  234. // Function: DynamicTextFont::set_page_size
  235. // Access: Published
  236. // Description: Sets the x, y size of the textures that are created
  237. // for the DynamicTextFont.
  238. ////////////////////////////////////////////////////////////////////
  239. INLINE void DynamicTextFont::
  240. set_page_size(int x_size, int y_size) {
  241. _page_x_size = x_size;
  242. _page_y_size = y_size;
  243. }
  244. ////////////////////////////////////////////////////////////////////
  245. // Function: DynamicTextFont::get_page_x_size
  246. // Access: Published
  247. // Description: Returns the x size of the textures that are created
  248. // for the DynamicTextFont. See set_page_size().
  249. ////////////////////////////////////////////////////////////////////
  250. INLINE int DynamicTextFont::
  251. get_page_x_size() const {
  252. return _page_x_size;
  253. }
  254. ////////////////////////////////////////////////////////////////////
  255. // Function: DynamicTextFont::get_page_y_size
  256. // Access: Published
  257. // Description: Returns the y size of the textures that are created
  258. // for the DynamicTextFont. See set_page_size().
  259. ////////////////////////////////////////////////////////////////////
  260. INLINE int DynamicTextFont::
  261. get_page_y_size() const {
  262. return _page_y_size;
  263. }
  264. ////////////////////////////////////////////////////////////////////
  265. // Function: DynamicTextFont::set_minfilter
  266. // Access: Published
  267. // Description: Sets the filter type used when minimizing the
  268. // textures created for this font.
  269. ////////////////////////////////////////////////////////////////////
  270. INLINE void DynamicTextFont::
  271. set_minfilter(Texture::FilterType filter) {
  272. _minfilter = filter;
  273. update_filters();
  274. }
  275. ////////////////////////////////////////////////////////////////////
  276. // Function: DynamicTextFont::get_minfilter
  277. // Access: Published
  278. // Description: Returns the filter type used when minimizing the
  279. // textures created for this font.
  280. ////////////////////////////////////////////////////////////////////
  281. INLINE Texture::FilterType DynamicTextFont::
  282. get_minfilter() const {
  283. return _minfilter;
  284. }
  285. ////////////////////////////////////////////////////////////////////
  286. // Function: DynamicTextFont::set_magfilter
  287. // Access: Published
  288. // Description: Sets the filter type used when enlarging the
  289. // textures created for this font.
  290. ////////////////////////////////////////////////////////////////////
  291. INLINE void DynamicTextFont::
  292. set_magfilter(Texture::FilterType filter) {
  293. _magfilter = filter;
  294. update_filters();
  295. }
  296. ////////////////////////////////////////////////////////////////////
  297. // Function: DynamicTextFont::get_magfilter
  298. // Access: Published
  299. // Description: Returns the filter type used when enlarging the
  300. // textures created for this font.
  301. ////////////////////////////////////////////////////////////////////
  302. INLINE Texture::FilterType DynamicTextFont::
  303. get_magfilter() const {
  304. return _magfilter;
  305. }
  306. ////////////////////////////////////////////////////////////////////
  307. // Function: DynamicTextFont::set_anisotropic_degree
  308. // Access: Published
  309. // Description: Enables or disables anisotropic filtering on the
  310. // textures created for this font. The default value is
  311. // specified by the text-anisotropic-degree variable.
  312. // See Texture::set_anisotropic_degree().
  313. ////////////////////////////////////////////////////////////////////
  314. INLINE void DynamicTextFont::
  315. set_anisotropic_degree(int anisotropic_degree) {
  316. _anisotropic_degree = anisotropic_degree;
  317. update_filters();
  318. }
  319. ////////////////////////////////////////////////////////////////////
  320. // Function: DynamicTextFont::get_anisotropic_degree
  321. // Access: Published
  322. // Description: Returns the current anisotropic degree for textures
  323. // created for this font. See set_anisotropic_degree().
  324. ////////////////////////////////////////////////////////////////////
  325. INLINE int DynamicTextFont::
  326. get_anisotropic_degree() const {
  327. return _anisotropic_degree;
  328. }
  329. ////////////////////////////////////////////////////////////////////
  330. // Function: DynamicTextFont::set_render_mode
  331. // Access: Published
  332. // Description: Specifies the way the glyphs on this particular font
  333. // are generated. The default is RM_texture, which is
  334. // the only mode supported for bitmap fonts. Other modes
  335. // are possible for most modern fonts.
  336. ////////////////////////////////////////////////////////////////////
  337. INLINE void DynamicTextFont::
  338. set_render_mode(DynamicTextFont::RenderMode render_mode) {
  339. _render_mode = render_mode;
  340. }
  341. ////////////////////////////////////////////////////////////////////
  342. // Function: DynamicTextFont::get_render_mode
  343. // Access: Published
  344. // Description: Returns the way the glyphs on this particular font
  345. // are generated. See set_render_mode().
  346. ////////////////////////////////////////////////////////////////////
  347. INLINE DynamicTextFont::RenderMode DynamicTextFont::
  348. get_render_mode() const {
  349. return _render_mode;
  350. }
  351. ////////////////////////////////////////////////////////////////////
  352. // Function: DynamicTextFont::set_winding_order
  353. // Access: Published
  354. // Description: Specifies an explicitly winding order on this
  355. // particular font. This is only necessary if the
  356. // render_mode is RM_polygon or RM_solid, and only if
  357. // FreeType appears to guess wrong on this font.
  358. // Normally, you should leave this at WO_default.
  359. ////////////////////////////////////////////////////////////////////
  360. INLINE void DynamicTextFont::
  361. set_winding_order(DynamicTextFont::WindingOrder winding_order) {
  362. _winding_order = winding_order;
  363. }
  364. ////////////////////////////////////////////////////////////////////
  365. // Function: DynamicTextFont::get_winding_order
  366. // Access: Published
  367. // Description: Returns the winding order set via set_winding_order().
  368. ////////////////////////////////////////////////////////////////////
  369. INLINE DynamicTextFont::WindingOrder DynamicTextFont::
  370. get_winding_order() const {
  371. return _winding_order;
  372. }
  373. ////////////////////////////////////////////////////////////////////
  374. // Function: DynamicTextFont::set_fg
  375. // Access: Published
  376. // Description: Changes the color of the foreground pixels of the
  377. // font as they are rendered into the font texture. The
  378. // default is (1, 1, 1, 1), or opaque white, which
  379. // allows text created with the font to be colored
  380. // individually. Normally, you would not change this
  381. // unless you really need a particular color effect to
  382. // appear in the font itself.
  383. //
  384. // This should only be called before any characters have
  385. // been requested out of the font, or immediately after
  386. // calling clear().
  387. ////////////////////////////////////////////////////////////////////
  388. INLINE void DynamicTextFont::
  389. set_fg(const Colorf &fg) {
  390. // If this assertion fails, you didn't call clear() first. RTFM.
  391. nassertv(get_num_pages() == 0);
  392. _fg = fg;
  393. determine_tex_format();
  394. }
  395. ////////////////////////////////////////////////////////////////////
  396. // Function: DynamicTextFont::get_fg
  397. // Access: Published
  398. // Description: Returns the color of the foreground pixels of the
  399. // font as they are rendered into the font texture.
  400. // See set_fg().
  401. ////////////////////////////////////////////////////////////////////
  402. INLINE const Colorf &DynamicTextFont::
  403. get_fg() const {
  404. return _fg;
  405. }
  406. ////////////////////////////////////////////////////////////////////
  407. // Function: DynamicTextFont::set_bg
  408. // Access: Published
  409. // Description: Changes the color of the background pixels of the
  410. // font as they are rendered into the font texture. The
  411. // default is (1, 1, 1, 0), or transparent white, which
  412. // allows text created with the font to be colored
  413. // individually. (Note that it should not generally be
  414. // (0, 0, 0, 0), which would tend to bleed into the
  415. // foreground color, unless you have also specified a
  416. // outline color of (0, 0, 0, 1)) .
  417. //
  418. // Normally, you would not change this unless you really
  419. // need a particular color effect to appear in the font
  420. // itself.
  421. //
  422. // This should only be called before any characters have
  423. // been requested out of the font, or immediately after
  424. // calling clear().
  425. ////////////////////////////////////////////////////////////////////
  426. INLINE void DynamicTextFont::
  427. set_bg(const Colorf &bg) {
  428. // If this assertion fails, you didn't call clear() first. RTFM.
  429. nassertv(get_num_pages() == 0);
  430. _bg = bg;
  431. determine_tex_format();
  432. }
  433. ////////////////////////////////////////////////////////////////////
  434. // Function: DynamicTextFont::get_bg
  435. // Access: Published
  436. // Description: Returns the color of the background pixels of the
  437. // font as they are rendered into the font texture.
  438. // See set_bg().
  439. ////////////////////////////////////////////////////////////////////
  440. INLINE const Colorf &DynamicTextFont::
  441. get_bg() const {
  442. return _bg;
  443. }
  444. ////////////////////////////////////////////////////////////////////
  445. // Function: DynamicTextFont::set_outline
  446. // Access: Published
  447. // Description: Sets up the font to have an outline around each font
  448. // letter. This is achieved via a Gaussian post-process
  449. // as each letter is generated; there is some runtime
  450. // cost for this effect, but it is minimal as each
  451. // letter is normally generated only once and then
  452. // cached.
  453. //
  454. // The color is the desired color of the outline, width
  455. // is the number of points beyond the letter that the
  456. // outline extends (a typical font is 10 points high),
  457. // and feather is a number in the range 0.0 .. 1.0 that
  458. // controls the softness of the outline. Set the width
  459. // to 0.0 to disable the outline.
  460. //
  461. // This should only be called before any characters have
  462. // been requested out of the font, or immediately after
  463. // calling clear().
  464. ////////////////////////////////////////////////////////////////////
  465. INLINE void DynamicTextFont::
  466. set_outline(const Colorf &outline_color, float outline_width,
  467. float outline_feather) {
  468. // If this assertion fails, you didn't call clear() first. RTFM.
  469. nassertv(get_num_pages() == 0);
  470. _outline_color = outline_color;
  471. _outline_width = outline_width;
  472. _outline_feather = outline_feather;
  473. determine_tex_format();
  474. }
  475. ////////////////////////////////////////////////////////////////////
  476. // Function: DynamicTextFont::get_outline_color
  477. // Access: Published
  478. // Description: Returns the color of the outline pixels of the
  479. // font as they are rendered into the font texture.
  480. // See set_outline().
  481. ////////////////////////////////////////////////////////////////////
  482. INLINE const Colorf &DynamicTextFont::
  483. get_outline_color() const {
  484. return _outline_color;
  485. }
  486. ////////////////////////////////////////////////////////////////////
  487. // Function: DynamicTextFont::get_outline_width
  488. // Access: Published
  489. // Description: Returns the width of the outline pixels of the
  490. // font, as the number of points beyond each letter.
  491. // See set_outline().
  492. ////////////////////////////////////////////////////////////////////
  493. INLINE float DynamicTextFont::
  494. get_outline_width() const {
  495. return _outline_width;
  496. }
  497. ////////////////////////////////////////////////////////////////////
  498. // Function: DynamicTextFont::get_outline_feather
  499. // Access: Published
  500. // Description: Returns the softness of the outline pixels of the
  501. // font, as a value in the range 0.0 to 1.0.
  502. // See set_outline().
  503. ////////////////////////////////////////////////////////////////////
  504. INLINE float DynamicTextFont::
  505. get_outline_feather() const {
  506. return _outline_feather;
  507. }
  508. ////////////////////////////////////////////////////////////////////
  509. // Function: DynamicTextFont::get_tex_format
  510. // Access: Published
  511. // Description: Returns the texture format used to render the
  512. // individual pages. This is set automatically
  513. // according to the colors selected.
  514. ////////////////////////////////////////////////////////////////////
  515. INLINE Texture::Format DynamicTextFont::
  516. get_tex_format() const {
  517. return _tex_format;
  518. }
  519. ////////////////////////////////////////////////////////////////////
  520. // Function: DynamicTextFont::ContourPoint::Constructor
  521. // Access: Public
  522. // Description:
  523. ////////////////////////////////////////////////////////////////////
  524. INLINE DynamicTextFont::ContourPoint::
  525. ContourPoint(const LPoint2f &p, const LVector2f &in, const LVector2f &out) :
  526. _p(p), _in(in), _out(out)
  527. {
  528. }
  529. ////////////////////////////////////////////////////////////////////
  530. // Function: DynamicTextFont::ContourPoint::Constructor
  531. // Access: Public
  532. // Description:
  533. ////////////////////////////////////////////////////////////////////
  534. INLINE DynamicTextFont::ContourPoint::
  535. ContourPoint(float px, float py, float tx, float ty) :
  536. _p(px, py), _in(tx, ty), _out(tx, ty)
  537. {
  538. }
  539. ////////////////////////////////////////////////////////////////////
  540. // Function: DynamicTextFont::connect_to
  541. // Access: Public
  542. // Description: Connects the indicated point to the next point, whose
  543. // tangent is given. The given tangent becomes the out
  544. // tangent at this point. If the in tangent and out
  545. // tangent are sufficiently close, they will be smoothed
  546. // together.
  547. ////////////////////////////////////////////////////////////////////
  548. INLINE void DynamicTextFont::ContourPoint::
  549. connect_to(const LVector2f &out) {
  550. _out = out;
  551. if (_in.dot(_out) > 0.7071) {
  552. // Less than 45 degrees of difference: smooth them.
  553. LVector2f av = (_in + _out) * 0.5f;
  554. av.normalize();
  555. _in = av;
  556. _out = av;
  557. }
  558. }
  559. INLINE ostream &
  560. operator << (ostream &out, const DynamicTextFont &dtf) {
  561. return out << dtf.get_name();
  562. }