在swift中设置和创建段落样式

时间:2014-10-12 10:20:13

标签: xcode text swift pdf-generation text-alignment

我正在尝试移植一个客观的C方法来将PDF上下文中的文本绘制到Swift中。 我可以转换大部分代码,但以下几行给我一个问题。 转换中的一些帮助将是受欢迎的。 这里是Objective C代码:

-(void)drawText:(NSString *)textToDraw context:(CGContextRef)myPDFContext textcolor:(NSColor *)textcolor  textfont:(NSFont*)textfont textbox:(CGRect)boxsize pagesize:(CGSize)pageSize {

   //     .........

   //    create paragraph style and assign text alignment to it
   CTTextAlignment alignment = kCTJustifiedTextAlignment;
   CTParagraphStyleSetting _settings[] = {    {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment} };
   CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(_settings, sizeof(_settings) / sizeof(_settings[0]));

   //    set paragraph style attribute
   CFAttributedStringSetAttribute(attrStr, CFRangeMake(0,   CFAttributedStringGetLength(attrStr)), kCTParagraphStyleAttributeName, paragraphStyle);

   //     .........
}

 // The following lines are my try in Swift, but this gives errors:
func DrawText(textToDraw:String, myPDFContext:CGContextRef, textcolor:NSColor,    textfont:NSFont, boxsize:CGRect, pagesize:CGSize) {
  var alignment = CTTextAlignment.TextAlignmentLeft
  let alignmentSetting = CTParagraphStyleSetting(spec:  CTParagraphStyleSpecifier.Alignment, valueSize: sizeof(alignment), value: &alignment)
  let paragraphStyle = CTParagraphStyleCreate(alignmentSetting, 1)
  //.......

如果这个问题得到解决,我可以在Swift中发布完整的方法。

2 个答案:

答案 0 :(得分:6)

我认为这样做:

var alignment = CTTextAlignment.TextAlignmentLeft
let alignmentSetting = [CTParagraphStyleSetting(spec: .Alignment, valueSize: UInt(sizeofValue(alignment)), value: &alignment)]
let paragraphStyle = CTParagraphStyleCreate(alignmentSetting, 1)
CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, CFAttributedStringGetLength(attrStr)), kCTParagraphStyleAttributeName, paragraphStyle)

我做了以下修改:

  1. 我将sizeof(alignment)更改为UInt(sizeofValue(alignment)),因为Swift中的sizeof只采用某种类型(例如sizeof(Int))。 UInt()是一个构造函数,可将Int返回的sizeofValue转换为此调用所需的UInt
  2. 我将alignmentSetting转换为数组,以便将其传递给该类型的UnsafePointer。这也更符合原始版本。
  3. 我将CTParagraphStyleSpecifier.Alignment更改为.Alignment,因为spec类型为CTParagraphStyleSpecifier,因此不需要第一部分。
  4. 在这种情况下,硬编码的1是正常的,因为您只传递了一个值,但更通用的解决方案是:

    let paragraphStyle = CTParagraphStyleCreate(alignmentSetting, UInt(alignmentSetting.count))
    

答案 1 :(得分:0)

这里是基于更正和帮助的完整工作方法。

func drawText(textToDraw:String, myPDFContext:CGContextRef, textcolor:NSColor,  textfont:NSFont, boxsize:CGRect, pagesize:CGSize) {
    let _font = NSFont(name:textfont.fontName, size:textfont.pointSize )
    if (_font == nil) {
        println("Font [\(textfont)] does not exist")
        return
    }

    let myBoxWidth = boxsize.size.width
    let myBoxHeight = boxsize.size.height
    let myBoxxpos = boxsize.origin.x
    let myBoxypos = boxsize.origin.y
    let frameRect = CGRectMake(myBoxxpos, myBoxypos,myBoxWidth,myBoxHeight);

     let framePath = CGPathCreateMutable()
     CGPathAddRect(framePath, nil, frameRect);

     //    create attributed string
     let attrStr = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
     CFAttributedStringReplaceString (attrStr, CFRangeMake(0, 0), textToDraw);

    //    create font
    let font = CTFontCreateWithName(textfont.fontName, textfont.pointSize, nil);

 var alignment = CTTextAlignment.TextAlignmentLeft
    let alignmentSetting = [CTParagraphStyleSetting(spec: .Alignment, valueSize: UInt(sizeofValue(alignment)), value: &alignment)]
    //let paragraphStyle = CTParagraphStyleCreate(alignmentSetting, 1)
    let paragraphStyle = CTParagraphStyleCreate(alignmentSetting, UInt(alignmentSetting.count))
    CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, CFAttributedStringGetLength(attrStr)), kCTParagraphStyleAttributeName, paragraphStyle)

 //    set font attribute
 CFAttributedStringSetAttribute(attrStr, CFRangeMake(0, CFAttributedStringGetLength(attrStr)), kCTFontAttributeName, font);

 //    set color attribute
 CFAttributedStringSetAttribute(attrStr,CFRangeMake(0, CFAttributedStringGetLength(attrStr)), kCTForegroundColorAttributeName,textcolor.CGColor);

 // Prepare the text using a Core Text Framesetter.
 let framesetter = CTFramesetterCreateWithAttributedString(attrStr);

 // Get the frame that will do the rendering.
 let currentRange = CFRangeMake(0, 0);
 let frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, nil);

 // Put the text matrix into a known state. This ensures
 // that no old scaling factors are left in place.
 CGContextSetTextMatrix(myPDFContext, CGAffineTransformIdentity);

 // Draw the frame.
 CTFrameDraw(frameRef, myPDFContext);
}