gvtextlayout_quartz.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. #include "config.h"
  11. #include <stdbool.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <gvc/gvplugin_textlayout.h>
  15. #include "gvplugin_quartz.h"
  16. #ifdef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
  17. #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 30200
  18. #include <CoreText/CoreText.h>
  19. #endif
  20. #endif
  21. #if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
  22. __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050) || \
  23. (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
  24. __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 30200)
  25. #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
  26. #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060
  27. /* symbol defined in 10.5.x dylib but not in headers */
  28. extern const CFStringRef kCTForegroundColorFromContextAttributeName;
  29. #endif
  30. #endif
  31. void *quartz_new_layout(char* fontname, double fontsize, char* text)
  32. {
  33. CFStringRef fontnameref = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)fontname, strlen(fontname), kCFStringEncodingUTF8, FALSE);
  34. CFStringRef textref = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)text, strlen(text), kCFStringEncodingUTF8, FALSE);
  35. CTLineRef line = NULL;
  36. if (fontnameref && textref) {
  37. /* set up the Core Text line */
  38. CTFontRef font = CTFontCreateWithName(fontnameref, fontsize, NULL);
  39. CFTypeRef attributeNames[] = { kCTFontAttributeName, kCTForegroundColorFromContextAttributeName };
  40. CFTypeRef attributeValues[] = { font, kCFBooleanTrue };
  41. CFDictionaryRef attributes = CFDictionaryCreate(
  42. kCFAllocatorDefault,
  43. (const void**)attributeNames,
  44. (const void**)attributeValues,
  45. 2,
  46. &kCFTypeDictionaryKeyCallBacks,
  47. &kCFTypeDictionaryValueCallBacks);
  48. CFAttributedStringRef attributed = CFAttributedStringCreate(kCFAllocatorDefault, textref, attributes);
  49. line = CTLineCreateWithAttributedString(attributed);
  50. CFRelease(attributed);
  51. CFRelease(attributes);
  52. CFRelease(font);
  53. }
  54. if (textref)
  55. CFRelease(textref);
  56. if (fontnameref)
  57. CFRelease(fontnameref);
  58. return (void *)line;
  59. }
  60. void quartz_size_layout(void *layout, double* width, double* height, double* yoffset_layout)
  61. {
  62. /* get the typographic bounds */
  63. CGFloat ascent = 0.0;
  64. CGFloat descent = 0.0;
  65. CGFloat leading = 0.0;
  66. *width = CTLineGetTypographicBounds(layout, &ascent, &descent, &leading);
  67. *height = ascent + descent + leading;
  68. *yoffset_layout = ascent;
  69. }
  70. void quartz_draw_layout(void *layout, CGContextRef context, CGPoint position)
  71. {
  72. CGContextSetTextPosition(context, position.x, position.y);
  73. CTLineDraw(layout, context);
  74. }
  75. void quartz_free_layout(void *layout)
  76. {
  77. if (layout)
  78. CFRelease(layout);
  79. };
  80. #endif
  81. static bool quartz_textlayout(textspan_t *para, char **fontpath)
  82. {
  83. (void)fontpath;
  84. void *line = quartz_new_layout(para->font->name, para->font->size, para->str);
  85. if (line)
  86. {
  87. /* report the layout */
  88. para->layout = line;
  89. para->free_layout = &quartz_free_layout;
  90. quartz_size_layout(line, &para->size.x, &para->size.y, &para->yoffset_layout);
  91. para->yoffset_centerline = 0.2 * para->font->size;
  92. return true;
  93. }
  94. else
  95. return false;
  96. };
  97. static gvtextlayout_engine_t quartz_textlayout_engine = {
  98. quartz_textlayout
  99. };
  100. gvplugin_installed_t gvtextlayout_quartz_types[] = {
  101. {0, "textlayout", 8, &quartz_textlayout_engine, NULL},
  102. {0, NULL, 0, NULL, NULL}
  103. };