Guest User

Untitled

a guest
Feb 20th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.32 KB | None | 0 0
  1. /**
  2. * Returns the lowest index of the matching line in the frame,
  3. * or -1 if no line in the frame matched.
  4. */
  5. static CFIndex MTFrameGetFirstLine(CTFrameRef frame, CFIndex charIndex, CTLineRef *found, CFRange *characterRange)
  6. {
  7. const CFArrayRef lines = CTFrameGetLines(frame);
  8. CFIndex l = 0, u = CFArrayGetCount(lines);
  9. while (l < u) {
  10. const CFIndex m = l + ((u - l) / 2);
  11. const CTLineRef line = CFArrayGetValueAtIndex(lines, m);
  12. const CFRange range = CTLineGetStringRange(line);
  13. const CFIndex t = charIndex - range.location;
  14.  
  15. if (t < 0) u = m;
  16. else if (t >= range.length) l = m + 1;
  17. else {
  18. if (found != NULL) *found = line;
  19. if (characterRange != NULL) *characterRange = range;
  20. return m;
  21. }
  22. }
  23.  
  24. return -1;
  25. }
  26.  
  27. /**
  28. * Returns a line origin for a frame.
  29. */
  30. CGPoint MTFrameGetLineOriginAtIndex(CTFrameRef frame, CFIndex index) {
  31. CGPoint origin;
  32. CTFrameGetLineOrigins(frame, CFRangeMake(index, 1), &origin);
  33. return origin;
  34. }
  35.  
  36. /**
  37. * Calculates the typographic bounds of a line.
  38. */
  39. static CGSize MTLineGetTypographicSize(CTLineRef line) {
  40. CGFloat ascent, descent, leading;
  41. double w = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
  42.  
  43. if (w > 0.0) {
  44. const double h = ascent + descent + leading;
  45. w -= CTLineGetTrailingWhitespaceWidth(line);
  46.  
  47. return CGSizeMake(
  48. w > CGFLOAT_MAX ? CGFLOAT_MAX : (CGFloat) w,
  49. h > CGFLOAT_MAX ? CGFLOAT_MAX : (CGFloat) h
  50. );
  51. }
  52. return CGSizeZero;
  53. }
  54.  
  55. static CGRect MTLineGetFirstRectForCharacterAtIndex(CTFrameRef frame, CTLineRef line, CFIndex lineIndex, CFIndex charIndex, Boolean verticalForms) {
  56. const CGRect box = MTFrameGetBoundingBox(frame);
  57. const CGPoint origin = MTFrameGetLineOriginAtIndex(frame, lineIndex);
  58. const CGFloat offset = CTLineGetOffsetForStringIndex(line, charIndex, NULL);
  59. const CGSize size = MTLineGetTypographicSize(line);
  60.  
  61. if (CGSizeEqualToSize(size, CGSizeZero)) return CGRectNull;
  62. if (!verticalForms) {
  63. return CGRectMake(
  64. origin.x + CGRectGetMinX(box) + offset,
  65. origin.y - CGRectGetMinY(box),
  66. size.width - offset,
  67. size.height
  68. );
  69. } else {
  70. return CGRectMake(
  71. origin.x,
  72. origin.y - size.width + CGRectGetMinY(box),
  73. size.height,
  74. size.width - offset
  75. );
  76. }
  77. }
Add Comment
Please, Sign In to add comment