2010-05-05 3 views
3

У меня есть NSView, который содержит много CALayers. Когда пользователь редактирует документ, эти CALayers оживляют все изменения. Я пытаюсь реализовать печать для своего приложения, но у меня возникают проблемы с правильной печатью этих CALayers.Печать CALayers

Некоторые границы CALayers занимают весь NSView, и их не нужно планировать, потому что их положение никогда не меняется. Однако у меня также есть один CALayer, который содержит около 20 небольших CALayers. Эти CALayers ожидают изменения своих позиций во время обычного редактирования. Однако при попытке распечатать NSView эти небольшие CALayers никогда не будут правильно расставлены. Мне интересно, есть ли что-то особенное, что я должен сделать, чтобы обеспечить правильное размещение этих слоев и позволить NSView правильно рисовать/печатать.

Есть ли у кого-нибудь опыт печати поддержки NSView с поддержкой Core Animation? Любые предложения приветствуются.

ответ

5

Для решения проблем с размещением, а также того факта, что использование иерархии слоев для создания иерархии слоев не сохраняет векторные элементы, мы подклассифицировали CALayer в Core Plot framework. Подкласс CPLayer переопределяет метод по умолчанию -drawInContext: для вызова нашего настраиваемого метода -renderAsVectorInContext: (где мы делаем все наши чертежи Core Graphics для слоя). Чтобы создать контекст PDF (или аналогичный) для печати, затем мы называем пользовательский метод с помощью следующего кода:

-(void)recursivelyRenderInContext:(CGContextRef)context 
{ 
    // render self 
    CGContextSaveGState(context); 

    [self applyTransform:self.transform toContext:context]; 

    self.renderingRecursively = YES; 
    if (!self.masksToBounds) { 
     CGContextSaveGState(context); 
    } 
    [self renderAsVectorInContext:context]; 
    if (!self.masksToBounds) { 
     CGContextRestoreGState(context); 
    } 
    self.renderingRecursively = NO; 

    // render sublayers 
    for (CALayer *currentSublayer in self.sublayers) { 
     CGContextSaveGState(context); 

     // Shift origin of context to match starting coordinate of sublayer 
     CGPoint currentSublayerFrameOrigin = currentSublayer.frame.origin; 
     CGRect currentSublayerBounds = currentSublayer.bounds; 
     CGContextTranslateCTM(context, 
           currentSublayerFrameOrigin.x - currentSublayerBounds.origin.x, 
           currentSublayerFrameOrigin.y - currentSublayerBounds.origin.y); 
     [self applyTransform:self.sublayerTransform toContext:context]; 
     if ([currentSublayer isKindOfClass:[CPLayer class]]) { 
      [(CPLayer *)currentSublayer recursivelyRenderInContext:context]; 
     } else { 
      if (self.masksToBounds) { 
       CGContextClipToRect(context, currentSublayer.bounds); 
      } 
      [currentSublayer drawInContext:context]; 
     } 
     CGContextRestoreGState(context); 
    } 
    CGContextRestoreGState(context); 
} 

Это проходит через и делаем каждый слой на плоский основных графический контекст, сохраняя положение, поворот и другие преобразования при рендеринге всех элементов как острых векторов.

Еще одна вещь, которую следует учитывать при попытке визуализации слоев, состоит в том, что состояние иерархии уровня представления может быть не таким, как ваша иерархия внутреннего уровня. У вас могут быть анимации, которые были применены для перемещения ваших слоев, но свойства слоев position, возможно, не были изменены для соответствия. В этом случае вы должны убедиться, что вы либо анимируете сами свойства, чтобы значения всегда находились в синхронизации, либо задавали значения в вашем слое после завершения анимации.

0

Последнее, что я просмотрел, не удалось правильно распечатать CALayers. Мне показалось, что Core Animation была предназначена только для экрана, а не для печати (что похоже на то, что она была первоначально разработана для iPhone).

Хотелось бы узнать, что я неправ.

Смежные вопросы