Problems displaying a glyph using appendBezierPathWithGlyphs

I am working with Objective-C ++.

I am trying to get the outline of a text using NSBezierPath appendBezierPathWithGlyphs. The problem is that the conclusion is pretty pointless :(

What I wrote:

  String str = Ascii8("test string");
  int length = str.getLength();

  NSFont* font = [NSFont fontWithDescriptor: [NSFontDescriptor fontDescriptorWithName:@"Times"
                                                                                 size:20]
                            textTransform: transform];

  NSTextStorage *storage = [[NSTextStorage alloc] initWithString:toNSString(str)];
  NSLayoutManager *manager = [[NSLayoutManager alloc] init];
  NSTextContainer *container = [[NSTextContainer alloc] init];

  [storage addLayoutManager:manager];
  [manager addTextContainer:container];

  NSGlyph* glyphs = new NSGlyph[length+1];
  [manager getGlyphs:glyphs range:NSMakeRange(0, length)];

  [container release];
  [manager release];
  [storage release];

  NSBezierPath* path = [NSBezierPath bezierPath];
  // If I don't do this I get an exception that currentPoint doesn't exist ...
  [path moveToPoint: NSMakePoint(0, 0)]; 
  [path appendBezierPathWithGlyphs:glyphs count:length inFont:font];

  delete[] glyphs;

  // NSBezierPath -> DoublePath
  for (NSInteger i=0; i<[path elementCount]; ++i)
  {
    NSPoint controlPoints[3];
    NSBezierPathElement el = [path elementAtIndex:i associatedPoints:controlPoints];
    if (el == NSMoveToBezierPathElement)
    {
      printf("move to (%f,%f)\n", controlPoints[0].x, controlPoints[0].y);
    }
    else if (el == NSLineToBezierPathElement)
    {
      printf("line to (%f, %f)\n", controlPoints[0].x, controlPoints[0].y);
    }
    else if (el == NSCurveToBezierPathElement)
    {
      printf("cubic to (%f, %f) (%f, %f) (%f, %f)\n", 
         controlPoints[0].x, controlPoints[0].y,
         controlPoints[1].x, controlPoints[1].y,
         controlPoints[2].x, controlPoints[2].y);
    }   
    else if (el == NSClosePathBezierPathElement) 
    {
      printf("close\n");
    }
  }

For example, for the letter "t" I get this output:

move to (0.277832, 0.000000)
move to (0.254395, 0.450195)
line to (0.254395, 0.415039)
line to (0.154785, 0.415039)
line to (0.153809, 0.133789)
cubic to (0.153809, 0.109049) (0.155924, 0.090332) (0.160156, 0.077637)
cubic to (0.167969, 0.055176) (0.183268, 0.043945) (0.206055, 0.043945)
cubic to (0.217773, 0.043945) (0.227946, 0.046712) (0.236572, 0.052246)
cubic to (0.245199, 0.057780) (0.255046, 0.066569) (0.266113, 0.078613)
line to (0.278809, 0.067871)
line to (0.268066, 0.053223)
cubic to (0.251139, 0.030436) (0.233236, 0,014323) (0.214355, 0.004883)
cubic to (0.195475, -0.004557) (0.177246, -0.009277) (0.159668, -0.009277)
cubic to (0.121256, -0.009277) (0.095215, 0.007812) (0.081543, 0.041992)
cubic to (0.074056, 0.060547) (0.070312, 0.086263) (0.070312, 0.119141)
line to (0.070312, 0.415039)
line to (0.017090, 0.415039)
cubic to (0.015462, 0.416016) (0.014242, 0.416992) (0.013428, 0.417969)
cubic to (0.012614, 0.418945) (0.012207, 0.420247) (0.012207, 0.421875)
cubic to (0.012207, 0.425130) (0.012939, 0.427653) (0.014404, 0.429443)
cubic to (0.015869, 0.431234) (0.020508, 0.435384) (0.028320, 0.441895)
cubic to (0.050781, 0.460449) (0.066976, 0.475504) (0.076904, 0.487061)
cubic to (0.086833, 0.498617) (0.110189, 0.529134) (0.146973, 0.578613)
cubic to (0.151204, 0.578613) (0.153727, 0.578288) (0.154541, 0.577637)
cubic to (0.155355, 0.576986) (0.155762, 0.574544) (0.155762, 0.570312)
line to (0.155762, 0.450195)
close

It looks really wrong to me!

+3
source share
1 answer

What do you mean by "looks wrong"? Have you tried to transfer data? Its reality.

, SVG , ( , SVG ). , ++ transform, undefined , , [manager numberOfGlyphs]. , .

NSString *str = @"test string";
int length = str.length;
NSAffineTransform *transform = [NSAffineTransform transform];

NSFont* font = [NSFont fontWithDescriptor: [NSFontDescriptor fontDescriptorWithName:@"Times" size:20]
                            textTransform: transform];

NSTextStorage *storage = [[NSTextStorage alloc] initWithString:str];
NSLayoutManager *manager = [[NSLayoutManager alloc] init];
NSTextContainer *container = [[NSTextContainer alloc] init];

[storage addLayoutManager:manager];
[manager addTextContainer:container];

NSUInteger glyphCount = [manager numberOfGlyphs];
NSGlyph glyphs[glyphCount];
[manager getGlyphs:glyphs range:NSMakeRange(0, glyphCount)];

[container release];
[manager release];
[storage release];

NSBezierPath* path = [NSBezierPath bezierPath];
[path moveToPoint: NSMakePoint(0, 0)]; // If I don't do this I get an exception that currentPoint doesn't exist ...
[path appendBezierPathWithGlyphs:glyphs count:length inFont:font];


printf("<?xml version=\"1.0\" standalone=\"no\"?>\n"
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
       "<svg viewBox=\"-5 -5 10 10\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n"
       "\t<desc>Debug dump</desc>\n"
       "\t\n<path d=\"");

// NSBezierPath -> DoublePath
for (NSInteger i=0; i<[path elementCount]; ++i)
{
    if (i != 0)  printf(" ");

    NSPoint controlPoints[3];
    NSBezierPathElement el = [path elementAtIndex:i associatedPoints:controlPoints];
    if (el == NSMoveToBezierPathElement)
    {
    //  printf("move to (%f,%f)\n", controlPoints[0].x, controlPoints[0].y);
        printf("M%g %g", controlPoints[0].x, controlPoints[0].y);
    }
    else if (el == NSLineToBezierPathElement)
    {
    //  printf("line to (%f, %f)\n", controlPoints[0].x, controlPoints[0].y);
        printf("L%g %g", controlPoints[0].x, controlPoints[0].y);
    }
    else if (el == NSCurveToBezierPathElement)
    {
    //  printf("cubic to (%f, %f) (%f, %f) (%f, %f)\n", 
        printf("C%g %g %g %g %g %g",
               controlPoints[0].x, controlPoints[0].y,
               controlPoints[1].x, controlPoints[1].y,
               controlPoints[2].x, controlPoints[2].y);
    }   
    else if (el == NSClosePathBezierPathElement) 
    {
    //  printf("close\n");
        printf("Z");
    }
}

printf("\"/>\n</svg>\n");
+2

Source: https://habr.com/ru/post/1764320/


All Articles