TextDrawable.m 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. //
  2. // TextDrawable.m
  3. // pdftest
  4. //
  5. // Created by Ray on 10/12/16.
  6. // Copyright © 2016 United Software Applications, Inc. All rights reserved.
  7. //
  8. #import "TextDrawable.h"
  9. #import <CoreText/CoreText.h>
  10. #import "TextUtils.h"
  11. @implementation TextDrawable
  12. -(instancetype) init:(CGRect) rect source_type:(NSString*) source_type source:(NSString*)source textAlignment:(NSString*)textAlignment vAlign:(NSString*)vAlign size:(NSString*)size
  13. {
  14. if (self = [super init]) {
  15. // NSMutableDictionary* m1=[drawableTemplate mutableCopy];
  16. // NSMutableDictionary* m2=[drawableTemplate mutableCopy];
  17. // [self setDrawableTemplate:[[RAUtils string2dict:[RAUtils dict2string:drawableTemplate]] mutableCopy] ];
  18. NSMutableDictionary * drawableTemplate = [TextDrawable createTextTemplate:rect source_type:source_type source:source textAlignment:textAlignment vAlign:vAlign size:size];
  19. [self setDrawableTemplate:[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:drawableTemplate]] ];
  20. }
  21. return self;
  22. }
  23. +(NSMutableDictionary *) createTextTemplate:(CGRect) rect source_type:(NSString*) source_type source:(NSString*)source textAlignment:(NSString*)textAlignment vAlign:(NSString*)vAlign size:(NSString*)size
  24. {
  25. if(textAlignment.length==0)
  26. textAlignment= @"Center";
  27. if(vAlign.length==0)
  28. vAlign= @"Middle";
  29. if(size.length==0)
  30. vAlign= @"10";
  31. NSMutableDictionary* ret=[super createDrawableTemplate:rect];
  32. ret[@"type"]=@"text" ;
  33. ret[@"source_type"]=source_type ;
  34. ret[@"source"]=source ;
  35. ret[@"text"]=source ;
  36. ret[@"textAlignment"]=textAlignment ;
  37. ret[@"vAlign"]=vAlign ;
  38. ret[@"size"]=size ;
  39. return ret;
  40. }
  41. -(void) setDrawableTemplate:(NSMutableDictionary *)drawableTemplate
  42. {
  43. [super setDrawableTemplate:drawableTemplate];
  44. NSString* align= drawableTemplate[@"textAlignment"];
  45. if(align.length==0 || [align.lowercaseString isEqualToString:@"left"])
  46. {
  47. self.textalignment= kCTTextAlignmentLeft;
  48. }
  49. else if([align.lowercaseString isEqualToString:@"right"])
  50. {
  51. self.textalignment= kCTTextAlignmentRight;
  52. }
  53. else if([align.lowercaseString isEqualToString:@"center"])
  54. {
  55. self.textalignment= kCTTextAlignmentCenter;
  56. }
  57. else
  58. {
  59. self.textalignment= kCTTextAlignmentLeft;
  60. }
  61. NSString* colorvalue=drawableTemplate[@"color"];
  62. if(colorvalue.length>0 )
  63. {
  64. unsigned long color = strtoul([colorvalue UTF8String],0,16);
  65. self.textColor= UIColorFromRGB(color);
  66. }
  67. else
  68. {
  69. self.textColor= [UIColor blackColor];
  70. }
  71. // kCTTextAlignmentJustified CT_ENUM_AVAILABLE(10_8, 6_0) = 3,
  72. // kCTTextAlignmentNatural CT_ENUM_AVAILABLE(10_8, 6_0) = 4,
  73. // _drawableTemplate = drawableTemplate;
  74. // self.margin_left=[self.drawableTemplate[@"margin_left"] doubleValue];
  75. // self.margin_right=[self.drawableTemplate[@"margin_right"] doubleValue];
  76. // self.margin_top=[self.drawableTemplate[@"margin_top"] doubleValue];
  77. // self.margin_bottom=[self.drawableTemplate[@"margin_bottom"] doubleValue];
  78. // self.rect = CGRectMake(0, 0, [self.drawableTemplate[@"width"] doubleValue], [self.drawableTemplate[@"height"] doubleValue]);
  79. }
  80. -(CGRect) Query_Rect:(CGContextRef) context dataSource:(NSMutableDictionary*)data ParentRect:(CGRect)p_rect startX:(double) x startY:(double) y flipHeight:(double)flip_height range:(NSRange)between_header_and_footer
  81. {
  82. bool expand=[self.drawableTemplate[@"expand"] boolValue];
  83. if(!expand)
  84. {
  85. CGRect parentrect = [self to_parent_rect:p_rect pos:self.rect offsetX:0 offsetY:0];
  86. return parentrect;
  87. }
  88. else
  89. {
  90. NSString * source=self.drawableTemplate[@"source_type"];
  91. if(source==nil)
  92. source=@"const";
  93. if([source isEqualToString:@"const"])
  94. {
  95. self.text=self.drawableTemplate[@"text"];
  96. // self.text=[self.text stringByReplacingOccurrencesOfString:@"\r\n" withString:@"<br>"];
  97. }
  98. else if([source isEqualToString:@"data"])
  99. {
  100. if([self.drawableTemplate[@"source_isexpression"] boolValue])
  101. {
  102. NSString *content = data[self.drawableTemplate[@"source"]];
  103. NSString *pattern = @"\\$\\.\\{([\\s\\S]*?)\\}\\.\\$";
  104. NSArray* matches=[TextUtils expression_varable:content regex:pattern];
  105. // if (matches) {
  106. // for (NSTextCheckingResult *match in matches) {
  107. // for (int i = 0; i < match.numberOfRanges; ++i) {
  108. // DebugLog(@"%d-> %@",i, [content substringWithRange:[match rangeAtIndex:i]]);
  109. // }
  110. // }
  111. // }
  112. if (matches)
  113. {
  114. self.text=content;
  115. for (NSTextCheckingResult *match in matches)
  116. {
  117. for (int i = 0; i < match.numberOfRanges/2; ++i) {
  118. DebugLog(@"%d-> %@",i, [content substringWithRange:[match rangeAtIndex:i]]);
  119. DebugLog(@"%d-> %@",i+1, [content substringWithRange:[match rangeAtIndex:i+1]]);
  120. self.text=[self.text stringByReplacingOccurrencesOfString:[content substringWithRange:[match rangeAtIndex:i]] withString:[NSString stringWithFormat:@"%@",data[[content substringWithRange:[match rangeAtIndex:i+1]]]]];
  121. }
  122. }
  123. }
  124. //self.text=content;
  125. }
  126. else
  127. {
  128. self.text=data[self.drawableTemplate[@"source"]];
  129. }
  130. }
  131. if(self.text==nil)
  132. self.text=@"";
  133. if([self.text isEqualToString:@"www.newpacificdirect.com"])
  134. {
  135. int debug=0;
  136. }
  137. bool bold = [self.drawableTemplate[@"bold"] boolValue];
  138. bool italic = [self.drawableTemplate[@"italic"] boolValue];
  139. NSString* font=self.drawableTemplate[@"font"];
  140. // [super flipContext:context ContextHeight:flip_height];
  141. // super flipContext:context ContextHeight:<#(double)#>
  142. CGFloat fontsize = [self.drawableTemplate[@"size"] doubleValue];
  143. //NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[title dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
  144. //创建AttributeStringfdsa
  145. NSMutableAttributedString *string = nil;
  146. // if([self.drawableTemplate[@"ishtml"] boolValue])
  147. // {
  148. // string=[[[NSAttributedString alloc] initWithData:[self.text dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil] mutableCopy];
  149. //
  150. // }
  151. // else
  152. {
  153. string=[[NSMutableAttributedString alloc] initWithString:self.text];
  154. //创建字体以及字体大小
  155. // CTFontRef ctfont = [self CreateFont:font size:fontsize bold:bold];//CTFontCreateWithName(CFSTR("Helvetica"), fontsize, NULL);
  156. // // CTFontRef helveticaBold = CTFontCreateWithName(CFSTR("Helvetica"), fontsize, NULL);
  157. // //字体,把helvetica 样式加到整个,string上
  158. // [string addAttribute:(id)kCTFontAttributeName
  159. // value:CFBridgingRelease(ctfont)
  160. // range:NSMakeRange(0, [string length])];
  161. //
  162. // //字体样式 ,把helveticaBold 样式加到整个,string上
  163. // // [string addAttribute:(id)kCTFontAttributeName
  164. // // value:CFBridgingRelease(helveticaBold)
  165. // // range:NSMakeRange(0, [string length])];
  166. //
  167. // //颜色,此处为黑色,你可以自己改颜色,[UIColor redColor]
  168. // [string addAttribute:(id)kCTForegroundColorAttributeName
  169. // value:(id)self.textColor.CGColor
  170. // range:NSMakeRange(0, [string length])];
  171. string = [self richtext2attributedstring:string font:font size:fontsize bold:bold];
  172. //设置字体间距
  173. long number = self.characterSpace;
  174. CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &number);
  175. [string addAttribute:(id)kCTKernAttributeName value:CFBridgingRelease(num) range:NSMakeRange(0, [string length])];
  176. //CFRelease(num);
  177. //创建文本对齐方式
  178. CTTextAlignment alignment = self.textalignment;//对齐方
  179. CTParagraphStyleSetting alignmentStyle;
  180. alignmentStyle.spec=kCTParagraphStyleSpecifierAlignment;
  181. alignmentStyle.valueSize=sizeof(alignment);
  182. alignmentStyle.value=&alignment;
  183. //创建文本, 行间距
  184. CGFloat lineSpace=self.lineSpace;//间距数据
  185. CTParagraphStyleSetting lineSpaceStyle;
  186. lineSpaceStyle.spec=kCTParagraphStyleSpecifierLineSpacing;
  187. lineSpaceStyle.valueSize=sizeof(lineSpace);
  188. lineSpaceStyle.value=&lineSpace;
  189. //设置 line break;
  190. CTLineBreakMode linebreakmode = kCTLineBreakByTruncatingTail;
  191. CTParagraphStyleSetting linebreakStyle;
  192. linebreakStyle.spec = kCTParagraphStyleSpecifierLineBreakMode;
  193. linebreakStyle.valueSize = sizeof(CGFloat);
  194. linebreakStyle.value = &linebreakmode;
  195. //设置 段落间距
  196. CGFloat paragraph = self.paragraphSpace;
  197. CTParagraphStyleSetting paragraphStyle;
  198. paragraphStyle.spec = kCTParagraphStyleSpecifierParagraphSpacing;
  199. paragraphStyle.valueSize = sizeof(CGFloat);
  200. paragraphStyle.value = &paragraph;
  201. //创建样式数组
  202. CTParagraphStyleSetting settings[]={
  203. alignmentStyle,lineSpaceStyle,paragraphStyle,linebreakStyle
  204. };
  205. //设置样式
  206. CTParagraphStyleRef paragraphStyle1 = CTParagraphStyleCreate(settings, sizeof(settings));
  207. //给字符串添加样式attribute
  208. [string addAttribute:(id)kCTParagraphStyleAttributeName
  209. value:CFBridgingRelease(paragraphStyle1)
  210. range:NSMakeRange(0, [string length])];
  211. }
  212. // CGRect pdfrect=[self to_parent_rect:p_rect pos:self.rect offsetX:0 offsetY:0];
  213. // [string drawInRect:pdfrect];
  214. // [self.text drawInRect:pdfrect withAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:40],NSForegroundColorAttributeName : [UIColor redColor]}];
  215. // layout master
  216. CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);
  217. //计算文本绘制size ,这里300是文字宽度,你可以自己更改为247,但是要记得,在height 方法里的这个位置,也改为247
  218. CGSize tmpSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0,0), NULL, CGSizeMake(self.rect.size.width-self.margin_left-self.margin_right, MAXFLOAT), NULL);
  219. //创建textBoxSize以设置view的frame
  220. CGSize textBoxSize = CGSizeMake((int)tmpSize.width + 1, (int)tmpSize.height + 1);
  221. // DebugLog(@"textBoxSize0 == %f,%f,%f",textBoxSize.width,textBoxSize.height,textBoxSize.width / textBoxSize.height);
  222. // self.frame = CGRectMake(0, 0, textBoxSize.width , textBoxSize.height);
  223. // [string release];
  224. //- (void)drawRect:(CGRect)rect;代码
  225. // CGMutablePathRef leftColumnPath = CGPathCreateMutable();
  226. CGRect parentrect = [self to_parent_rect:p_rect pos:self.rect offsetX:0 offsetY:0];
  227. double height =0;
  228. if(tmpSize.height<parentrect.size.height)
  229. height=tmpSize.height;
  230. else
  231. if(expand)
  232. {
  233. height=tmpSize.height;
  234. self.rect = CGRectMake(self.rect.origin.x, self.rect.origin.y, self.rect.size.width, height+self.margin_top+self.margin_bottom);
  235. }
  236. else
  237. height=parentrect.size.height;
  238. CGRect rect=CGRectMake(parentrect.origin.x, parentrect.origin.y, parentrect.size.width, height);
  239. CGRect expand_rect=rect;
  240. // CGRect rect=[RAUtils rectAlign:parentrect rect:scalerect hAlign:self.hAlign vAlign:self.vAlign];
  241. // rect=[RAUtils rectVAlign:parentrect rect:rect vAlign:self.vAlign];
  242. //
  243. // // CGRect pdfrect = [self to_pdf_rect:p_rect pos:self.rect contextHeight:flip_height];
  244. //
  245. // rect= [self parent_to_pdf_rect:rect contextHeight:flip_height];
  246. // // pdfrect=CGRectMake(pdfrect.origin.x, flip_height-pdfrect.origin.y, pdfrect.size.width, pdfrect.size.height);
  247. // CGPathAddRect(leftColumnPath, NULL,
  248. // rect);
  249. //
  250. // CTFrameRef leftFrame = CTFramesetterCreateFrame(framesetter,
  251. // CFRangeMake(0, 0),
  252. // leftColumnPath, NULL);
  253. //
  254. // // DebugLog(@"textBoxSize1 == %f,%f",self.frame.size.width,self.frame.size.height);
  255. // // flip the coordinate system
  256. // // CGContextRef context = UIGraphicsGetCurrentContext();
  257. //
  258. //
  259. // // CGContextClearRect(context, self.rect);
  260. // // CGContextSetFillColorWithColor(context, [[UIColor whiteColor]CGColor]);
  261. // // CGContextFillRect(context, CGRectMake(0, 0, self.rect.size.width, self.rect.size.height));
  262. //
  263. //
  264. // CGContextSetTextMatrix(context, CGAffineTransformIdentity);
  265. // // CGContextTranslateCTM(context, 0, self.rect.size.height);
  266. // // CGContextScaleCTM(context, 1.0, -1.0);
  267. //
  268. // // draw
  269. // CTFrameDraw(leftFrame, context);
  270. //
  271. //
  272. // CFRelease(leftFrame);
  273. // // cleanup
  274. //
  275. // CGPathRelease(leftColumnPath);
  276. CFRelease(framesetter);
  277. // return self.rect;
  278. // [self DrawBound:context dataSource:data ParentRect:p_rect startX:x startY:y flipHeight:flip_height range:between_header_and_footer];
  279. if(expand&&expand_rect.size.height>parentrect.size.height)
  280. return expand_rect;
  281. else
  282. return parentrect;
  283. // return CGPointMake(parentrect.origin.x+parentrect.size.width, parentrect.origin.y+parentrect.size.height);
  284. // [super restoreFlip:context ContextHeight:flip_height];
  285. }
  286. }
  287. -(CTFontRef)CreateFont:(NSString*)name size:(double)size bold:(bool)bold
  288. {
  289. if(name.length==0)
  290. {
  291. name=@"Helvetica";
  292. // name=@"DejaVu Sans";
  293. }
  294. if(size==0)
  295. {
  296. size=10;
  297. }
  298. NSString* style = @"Regular";
  299. if(bold)
  300. style=@"Bold";
  301. //name=@"Courier";
  302. NSDictionary *fontAttributes =
  303. [NSDictionary dictionaryWithObjectsAndKeys:
  304. name, (NSString *)kCTFontFamilyNameAttribute,
  305. style, (NSString *)kCTFontStyleNameAttribute,
  306. [NSNumber numberWithFloat:size],
  307. (NSString *)kCTFontSizeAttribute,
  308. nil];
  309. // Create a descriptor.
  310. CFDictionaryRef cffontAttributes =(__bridge CFDictionaryRef)fontAttributes;
  311. CTFontDescriptorRef descriptor =
  312. CTFontDescriptorCreateWithAttributes(cffontAttributes);
  313. // CFBridgingRelease(cffontAttributes);
  314. // Create a font using the descriptor.
  315. CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
  316. CFBridgingRelease(descriptor);
  317. return font;
  318. // if(bold)
  319. // {
  320. // CTFontRef font=CTFontCreateWithName((__bridge CFStringRef)name, size, NULL);
  321. // CTFontRef font_bold =CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, kCTFontBoldTrait, kCTFontBoldTrait);
  322. // CFBridgingRelease(font);
  323. // return font_bold;
  324. // }
  325. // return CTFontCreateWithName((__bridge CFStringRef)name, size, NULL);
  326. }
  327. //-(NSString*) QueryFontName:(NSString*)font
  328. //{
  329. // if(font==nil)
  330. // {
  331. // return @"Helvetica";
  332. // }
  333. // else if([font.lowercaseString isEqualToString:@"kalinga"])
  334. // {
  335. // return @"kalinga";
  336. // }
  337. // return @"Helvetica";
  338. //}
  339. -(NSMutableAttributedString*) richtext2attributedstring:(NSMutableAttributedString*)string font:(NSString*)font size:(double)size bold:(bool)bold
  340. {
  341. // UILabel* uilabel=[[UILabel alloc]init];
  342. // uilabel.font=[UIFont fontWithName:font size:size];
  343. // NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[self.text dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
  344. // uilabel.attributedText = attrStr;
  345. // DebugLog(@"%@", attrStr);
  346. // DebugLog(@"%@", uilabel.attributedText);
  347. CTFontRef ctfont = [self CreateFont:font size:size bold:bold];//CTFontCreateWithName(CFSTR("Helvetica"), fontsize, NULL);b
  348. //CTFontCreateWithName(CFSTR("Helvetica"), fontsize, NULL);
  349. // CTFontRef helveticaBold = CTFontCreateWithName(CFSTR("Helvetica"), fontsize, NULL);
  350. //字体,把helvetica 样式加到整个,string上
  351. [string addAttribute:(id)kCTFontAttributeName
  352. value:CFBridgingRelease(ctfont)
  353. range:NSMakeRange(0, [string length])];
  354. //颜色,此处为黑色,你可以自己改颜色,[UIColor redColor]
  355. [string addAttribute:(id)kCTForegroundColorAttributeName
  356. value:(id)self.textColor.CGColor
  357. range:NSMakeRange(0, [string length])];
  358. if(!bold)
  359. {
  360. CTFontRef ctfont_bold = [self CreateFont:font size:size bold:true];
  361. NSString* newstring= nil;
  362. // NSString *content = string.string ;
  363. NSString *pattern = @"\\<b\\>([\\s\\S]*?)\\<\\/b\\>";
  364. // NSArray* matches=[TextUtils expression_varable:content regex:pattern];
  365. // if (matches) {
  366. // for (NSTextCheckingResult *match in matches) {
  367. // for (int i = 0; i < match.numberOfRanges; ++i) {
  368. // DebugLog(@"%d-> %@",i, [content substringWithRange:[match rangeAtIndex:i]]);
  369. // }
  370. // }
  371. // }
  372. NSTextCheckingResult * match=[TextUtils expression_findfistMatch:string.string regex:pattern];
  373. while(match)
  374. {
  375. //for (int i = 0; i < match.numberOfRanges/2; ++i)
  376. {
  377. int i=0;
  378. DebugLog(@"%d->range with richtext label: %d,%d",i, [match rangeAtIndex:i].location,[match rangeAtIndex:i].length);
  379. DebugLog(@"%d-> range of text: %d,%d ",i+1, [match rangeAtIndex:i+1].location,[match rangeAtIndex:i+1].length);
  380. DebugLog(@"string length: %d",string.string.length);
  381. [string addAttribute:(id)kCTFontAttributeName
  382. value:(__bridge id _Nonnull)(ctfont_bold)
  383. range:[match rangeAtIndex:i+1]];
  384. [string replaceCharactersInRange:NSMakeRange([match rangeAtIndex:i+1].location+[match rangeAtIndex:i+1].length, [match rangeAtIndex:i].location+[match rangeAtIndex:i].length-([match rangeAtIndex:i+1].location+[match rangeAtIndex:i+1].length)) withString:@""];
  385. [string replaceCharactersInRange:NSMakeRange([match rangeAtIndex:i].location, [match rangeAtIndex:i+1].location-[match rangeAtIndex:i].location) withString:@""];
  386. DebugLog(@"string after replace: %@",string.string);
  387. //newstring=[newstring stringByReplacingOccurrencesOfString:[content substringWithRange:[match rangeAtIndex:i]] withString:[content substringWithRange:[match rangeAtIndex:i+1]]];
  388. match=[TextUtils expression_findfistMatch:string.string regex:pattern];
  389. }
  390. }
  391. // if (matches)
  392. // {
  393. // newstring=content;
  394. // for (NSTextCheckingResult *match in matches)
  395. // {
  396. //
  397. // for (int i = 0; i < match.numberOfRanges/2; ++i)
  398. // {
  399. // DebugLog(@"%d-> %@",i, [content substringWithRange:[match rangeAtIndex:i]]);
  400. // DebugLog(@"%d-> %@",i+1, [content substringWithRange:[match rangeAtIndex:i+1]]);
  401. //
  402. // [string addAttribute:(id)kCTFontAttributeName
  403. // value:CFBridgingRelease(ctfont_bold)
  404. // range:[match rangeAtIndex:i+1]];
  405. //
  406. // newstring=[newstring stringByReplacingOccurrencesOfString:[content substringWithRange:[match rangeAtIndex:i]] withString:[content substringWithRange:[match rangeAtIndex:i+1]]];
  407. //
  408. // }
  409. // }
  410. // }
  411. CFBridgingRelease(ctfont_bold);
  412. }
  413. return string;
  414. }
  415. -(CGRect) Draw:(CGContextRef) context dataSource:(NSMutableDictionary*)data ParentRect:(CGRect)p_rect startX:(double) x startY:(double) y flipHeight:(double)flip_height range:(NSRange)between_header_and_footer
  416. {
  417. NSString * source=self.drawableTemplate[@"source_type"];
  418. if(source==nil)
  419. source=@"const";
  420. if([source isEqualToString:@"const"])
  421. {
  422. self.text=self.drawableTemplate[@"text"];
  423. // self.text=[self.text stringByReplacingOccurrencesOfString:@"\r\n" withString:@"<br>"];
  424. }
  425. else if([source isEqualToString:@"data"])
  426. {
  427. if([self.drawableTemplate[@"source_isexpression"] boolValue])
  428. {
  429. NSString *content = data[self.drawableTemplate[@"source"]];
  430. NSString *pattern = @"\\$\\.\\{([\\s\\S]*?)\\}\\.\\$";
  431. NSArray* matches=[TextUtils expression_varable:content regex:pattern];
  432. // if (matches) {
  433. // for (NSTextCheckingResult *match in matches) {
  434. // for (int i = 0; i < match.numberOfRanges; ++i) {
  435. // DebugLog(@"%d-> %@",i, [content substringWithRange:[match rangeAtIndex:i]]);
  436. // }
  437. // }
  438. // }
  439. if (matches)
  440. {
  441. self.text=content;
  442. for (NSTextCheckingResult *match in matches)
  443. {
  444. for (int i = 0; i < match.numberOfRanges/2; ++i) {
  445. DebugLog(@"%d-> %@",i, [content substringWithRange:[match rangeAtIndex:i]]);
  446. DebugLog(@"%d-> %@",i+1, [content substringWithRange:[match rangeAtIndex:i+1]]);
  447. self.text=[self.text stringByReplacingOccurrencesOfString:[content substringWithRange:[match rangeAtIndex:i]] withString:[NSString stringWithFormat:@"%@",data[[content substringWithRange:[match rangeAtIndex:i+1]]]]];
  448. }
  449. }
  450. }
  451. //self.text=content;
  452. }
  453. else
  454. {
  455. self.text=data[self.drawableTemplate[@"source"]];
  456. }
  457. }
  458. if(self.text==nil)
  459. self.text=@"";
  460. // if([self.text isEqualToString:@"www.newpacificdirect.com"])
  461. // {
  462. // int debug=0;
  463. // }
  464. bool bold = [self.drawableTemplate[@"bold"] boolValue];
  465. bool italic = [self.drawableTemplate[@"italic"] boolValue];
  466. NSString* font=self.drawableTemplate[@"font"];
  467. // [super flipContext:context ContextHeight:flip_height];
  468. // super flipContext:context ContextHeight:<#(double)#>
  469. CGFloat fontsize = [self.drawableTemplate[@"size"] doubleValue];
  470. //NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[title dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
  471. //创建AttributeStringfdsa
  472. NSMutableAttributedString *string = nil;
  473. // if([self.drawableTemplate[@"ishtml"] boolValue])
  474. // {
  475. // string=[[[NSAttributedString alloc] initWithData:[self.text dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil] mutableCopy];
  476. //
  477. // }
  478. // else
  479. {
  480. string=[[NSMutableAttributedString alloc] initWithString:self.text];
  481. //创建字体以及字体大小
  482. // CTFontRef ctfont = [self CreateFont:font size:fontsize bold:bold];//CTFontCreateWithName(CFSTR("Helvetica"), fontsize, NULL);
  483. // // CTFontRef helveticaBold = CTFontCreateWithName(CFSTR("Helvetica"), fontsize, NULL);
  484. // //字体,把helvetica 样式加到整个,string上
  485. // [string addAttribute:(id)kCTFontAttributeName
  486. // value:CFBridgingRelease(ctfont)
  487. // range:NSMakeRange(0, [string length])];
  488. //
  489. // //字体样式 ,把helveticaBold 样式加到整个,string上
  490. // // [string addAttribute:(id)kCTFontAttributeName
  491. // // value:CFBridgingRelease(helveticaBold)
  492. // // range:NSMakeRange(0, [string length])];
  493. //
  494. // //颜色,此处为黑色,你可以自己改颜色,[UIColor redColor]
  495. // [string addAttribute:(id)kCTForegroundColorAttributeName
  496. // value:(id)self.textColor.CGColor
  497. // range:NSMakeRange(0, [string length])];
  498. string = [self richtext2attributedstring:string font:font size:fontsize bold:bold];
  499. //设置字体间距
  500. long number = self.characterSpace;
  501. CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &number);
  502. [string addAttribute:(id)kCTKernAttributeName value:CFBridgingRelease(num) range:NSMakeRange(0, [string length])];
  503. //CFRelease(num);
  504. //创建文本对齐方式
  505. CTTextAlignment alignment = self.textalignment;//对齐方
  506. CTParagraphStyleSetting alignmentStyle;
  507. alignmentStyle.spec=kCTParagraphStyleSpecifierAlignment;
  508. alignmentStyle.valueSize=sizeof(alignment);
  509. alignmentStyle.value=&alignment;
  510. //创建文本, 行间距
  511. CGFloat lineSpace=self.lineSpace;//间距数据
  512. CTParagraphStyleSetting lineSpaceStyle;
  513. lineSpaceStyle.spec=kCTParagraphStyleSpecifierLineSpacing;
  514. lineSpaceStyle.valueSize=sizeof(lineSpace);
  515. lineSpaceStyle.value=&lineSpace;
  516. //设置 line break;
  517. CTLineBreakMode linebreakmode = kCTLineBreakByTruncatingTail;
  518. CTParagraphStyleSetting linebreakStyle;
  519. linebreakStyle.spec = kCTParagraphStyleSpecifierLineBreakMode;
  520. linebreakStyle.valueSize = sizeof(CGFloat);
  521. linebreakStyle.value = &linebreakmode;
  522. //设置 段落间距
  523. CGFloat paragraph = self.paragraphSpace;
  524. CTParagraphStyleSetting paragraphStyle;
  525. paragraphStyle.spec = kCTParagraphStyleSpecifierParagraphSpacing;
  526. paragraphStyle.valueSize = sizeof(CGFloat);
  527. paragraphStyle.value = &paragraph;
  528. //创建样式数组
  529. CTParagraphStyleSetting settings[]={
  530. alignmentStyle,lineSpaceStyle,paragraphStyle,linebreakStyle
  531. };
  532. //设置样式
  533. CTParagraphStyleRef paragraphStyle1 = CTParagraphStyleCreate(settings, sizeof(settings));
  534. //给字符串添加样式attribute
  535. [string addAttribute:(id)kCTParagraphStyleAttributeName
  536. value:CFBridgingRelease(paragraphStyle1)
  537. range:NSMakeRange(0, [string length])];
  538. }
  539. // CGRect pdfrect=[self to_parent_rect:p_rect pos:self.rect offsetX:0 offsetY:0];
  540. // [string drawInRect:pdfrect];
  541. // [self.text drawInRect:pdfrect withAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:40],NSForegroundColorAttributeName : [UIColor redColor]}];
  542. // layout master
  543. CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);
  544. //计算文本绘制size ,这里300是文字宽度,你可以自己更改为247,但是要记得,在height 方法里的这个位置,也改为247
  545. CGSize tmpSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0,0), NULL, CGSizeMake(self.rect.size.width-self.margin_left-self.margin_right, MAXFLOAT), NULL);
  546. //创建textBoxSize以设置view的frame
  547. CGSize textBoxSize = CGSizeMake((int)tmpSize.width + 1, (int)tmpSize.height + 1);
  548. // DebugLog(@"textBoxSize0 == %f,%f,%f",textBoxSize.width,textBoxSize.height,textBoxSize.width / textBoxSize.height);
  549. // self.frame = CGRectMake(0, 0, textBoxSize.width , textBoxSize.height);
  550. // [string release];
  551. //- (void)drawRect:(CGRect)rect;代码
  552. CGMutablePathRef leftColumnPath = CGPathCreateMutable();
  553. CGRect parentrect = [self to_parent_rect:p_rect pos:self.rect offsetX:0 offsetY:0];
  554. bool expand=[self.drawableTemplate[@"expand"] boolValue];
  555. double height =0;
  556. if(tmpSize.height<parentrect.size.height)
  557. height=tmpSize.height;
  558. else
  559. if(expand)
  560. {
  561. height=tmpSize.height;
  562. self.rect = CGRectMake(self.rect.origin.x, self.rect.origin.y, self.rect.size.width, height+self.margin_top+self.margin_bottom);
  563. }
  564. else
  565. height=parentrect.size.height;
  566. CGRect rect=CGRectMake(parentrect.origin.x, parentrect.origin.y, parentrect.size.width, height);
  567. CGRect expand_rect=rect;
  568. // CGRect rect=[RAUtils rectAlign:parentrect rect:scalerect hAlign:self.hAlign vAlign:self.vAlign];
  569. rect=[TextUtils rectVAlign:parentrect rect:rect vAlign:self.vAlign];
  570. // CGRect pdfrect = [self to_pdf_rect:p_rect pos:self.rect contextHeight:flip_height];
  571. rect= [self parent_to_pdf_rect:rect contextHeight:flip_height];
  572. // pdfrect=CGRectMake(pdfrect.origin.x, flip_height-pdfrect.origin.y, pdfrect.size.width, pdfrect.size.height);
  573. CGPathAddRect(leftColumnPath, NULL,
  574. rect);
  575. CTFrameRef leftFrame = CTFramesetterCreateFrame(framesetter,
  576. CFRangeMake(0, 0),
  577. leftColumnPath, NULL);
  578. // DebugLog(@"textBoxSize1 == %f,%f",self.frame.size.width,self.frame.size.height);
  579. // flip the coordinate system
  580. // CGContextRef context = UIGraphicsGetCurrentContext();
  581. // CGContextClearRect(context, self.rect);
  582. // CGContextSetFillColorWithColor(context, [[UIColor whiteColor]CGColor]);
  583. // CGContextFillRect(context, CGRectMake(0, 0, self.rect.size.width, self.rect.size.height));
  584. CGContextSetTextMatrix(context, CGAffineTransformIdentity);
  585. // CGContextTranslateCTM(context, 0, self.rect.size.height);
  586. // CGContextScaleCTM(context, 1.0, -1.0);
  587. // draw
  588. CTFrameDraw(leftFrame, context);
  589. CFRelease(leftFrame);
  590. // cleanup
  591. CGPathRelease(leftColumnPath);
  592. CFRelease(framesetter);
  593. // return self.rect;
  594. [self DrawBound:context dataSource:data ParentRect:p_rect startX:x startY:y flipHeight:flip_height range:between_header_and_footer];
  595. if(expand&&expand_rect.size.height>parentrect.size.height)
  596. return expand_rect;
  597. else
  598. return parentrect;
  599. // return CGPointMake(parentrect.origin.x+parentrect.size.width, parentrect.origin.y+parentrect.size.height);
  600. // [super restoreFlip:context ContextHeight:flip_height];
  601. }
  602. @end