YYTextDebugOption.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. //
  2. // YYTextDebugOption.m
  3. // YYKit <https://github.com/ibireme/YYKit>
  4. //
  5. // Created by ibireme on 15/4/8.
  6. // Copyright (c) 2015 ibireme.
  7. //
  8. // This source code is licensed under the MIT-style license found in the
  9. // LICENSE file in the root directory of this source tree.
  10. //
  11. #import "YYTextDebugOption.h"
  12. #import "YYKitMacro.h"
  13. #import "UIColor+YYAdd.h"
  14. #import "YYWeakProxy.h"
  15. static pthread_mutex_t _sharedDebugLock;
  16. static CFMutableSetRef _sharedDebugTargets = nil;
  17. static YYTextDebugOption *_sharedDebugOption = nil;
  18. static const void* _sharedDebugSetRetain(CFAllocatorRef allocator, const void *value) {
  19. return value;
  20. }
  21. static void _sharedDebugSetRelease(CFAllocatorRef allocator, const void *value) {
  22. }
  23. void _sharedDebugSetFunction(const void *value, void *context) {
  24. id<YYTextDebugTarget> target = (__bridge id<YYTextDebugTarget>)(value);
  25. [target setDebugOption:_sharedDebugOption];
  26. }
  27. static void _initSharedDebug() {
  28. static dispatch_once_t onceToken;
  29. dispatch_once(&onceToken, ^{
  30. pthread_mutex_init(&_sharedDebugLock, NULL);
  31. CFSetCallBacks callbacks = kCFTypeSetCallBacks;
  32. callbacks.retain = _sharedDebugSetRetain;
  33. callbacks.release = _sharedDebugSetRelease;
  34. _sharedDebugTargets = CFSetCreateMutable(CFAllocatorGetDefault(), 0, &callbacks);
  35. });
  36. }
  37. static void _setSharedDebugOption(YYTextDebugOption *option) {
  38. _initSharedDebug();
  39. pthread_mutex_lock(&_sharedDebugLock);
  40. _sharedDebugOption = option.copy;
  41. CFSetApplyFunction(_sharedDebugTargets, _sharedDebugSetFunction, NULL);
  42. pthread_mutex_unlock(&_sharedDebugLock);
  43. }
  44. static YYTextDebugOption *_getSharedDebugOption() {
  45. _initSharedDebug();
  46. pthread_mutex_lock(&_sharedDebugLock);
  47. YYTextDebugOption *op = _sharedDebugOption;
  48. pthread_mutex_unlock(&_sharedDebugLock);
  49. return op;
  50. }
  51. static void _addDebugTarget(id<YYTextDebugTarget> target) {
  52. _initSharedDebug();
  53. pthread_mutex_lock(&_sharedDebugLock);
  54. CFSetAddValue(_sharedDebugTargets, (__bridge const void *)(target));
  55. pthread_mutex_unlock(&_sharedDebugLock);
  56. }
  57. static void _removeDebugTarget(id<YYTextDebugTarget> target) {
  58. _initSharedDebug();
  59. pthread_mutex_lock(&_sharedDebugLock);
  60. CFSetRemoveValue(_sharedDebugTargets, (__bridge const void *)(target));
  61. pthread_mutex_unlock(&_sharedDebugLock);
  62. }
  63. @implementation YYTextDebugOption
  64. - (id)copyWithZone:(NSZone *)zone {
  65. YYTextDebugOption *op = [self.class new];
  66. op.baselineColor = self.baselineColor;
  67. op.CTFrameBorderColor = self.CTFrameBorderColor;
  68. op.CTFrameFillColor = self.CTFrameFillColor;
  69. op.CTLineBorderColor = self.CTLineBorderColor;
  70. op.CTLineFillColor = self.CTLineFillColor;
  71. op.CTLineNumberColor = self.CTLineNumberColor;
  72. op.CTRunBorderColor = self.CTRunBorderColor;
  73. op.CTRunFillColor = self.CTRunFillColor;
  74. op.CTRunNumberColor = self.CTRunNumberColor;
  75. op.CGGlyphBorderColor = self.CGGlyphBorderColor;
  76. op.CGGlyphFillColor = self.CGGlyphFillColor;
  77. return op;
  78. }
  79. - (BOOL)needDrawDebug {
  80. if (self.baselineColor ||
  81. self.CTFrameBorderColor ||
  82. self.CTFrameFillColor ||
  83. self.CTLineBorderColor ||
  84. self.CTLineFillColor ||
  85. self.CTLineNumberColor ||
  86. self.CTRunBorderColor ||
  87. self.CTRunFillColor ||
  88. self.CTRunNumberColor ||
  89. self.CGGlyphBorderColor ||
  90. self.CGGlyphFillColor) return YES;
  91. return NO;
  92. }
  93. - (void)clear {
  94. self.baselineColor = nil;
  95. self.CTFrameBorderColor = nil;
  96. self.CTFrameFillColor = nil;
  97. self.CTLineBorderColor = nil;
  98. self.CTLineFillColor = nil;
  99. self.CTLineNumberColor = nil;
  100. self.CTRunBorderColor = nil;
  101. self.CTRunFillColor = nil;
  102. self.CTRunNumberColor = nil;
  103. self.CGGlyphBorderColor = nil;
  104. self.CGGlyphFillColor = nil;
  105. }
  106. + (void)addDebugTarget:(id<YYTextDebugTarget>)target {
  107. if (target) _addDebugTarget(target);
  108. }
  109. + (void)removeDebugTarget:(id<YYTextDebugTarget>)target {
  110. if (target) _removeDebugTarget(target);
  111. }
  112. + (YYTextDebugOption *)sharedDebugOption {
  113. return _getSharedDebugOption();
  114. }
  115. + (void)setSharedDebugOption:(YYTextDebugOption *)option {
  116. YYAssertMainThread();
  117. _setSharedDebugOption(option);
  118. }
  119. @end