simsong@daily-bugle.media.mit.edu (Simson L. Garfinkel) (01/11/91)
For the news reader, I had to be able to find the line breaks inside a Text object. If you use the NeXT methods that return character offsets by lines, you actually get paragraphs, not lines.
If you want to get the *real* line breaks, the ones that are displayed on the screen, then you have to decode the internal variable "theBreaks." It took me about 2 hours to figure out how to do that, and I'm posting the code here in case anybody else needs to do the similar thing:
/* This piece of code shows how to get line break information out of
* a Text object.
*
* (C) 1990 MIT Media Lab. By Simson L. Garfinkel
*/
#import "Thing.h"
#import <stdio.h>
#import <stdlib.h>
#import <appkit/ScrollView.h>
#import <appkit/Text.h>
@implementation Thing
- calc:sender
{
Text *text = [myScroller docView];
int line;
int pos;
NXBreakArray *theBreaks=0;
int nbreaks;
NXLineDesc *breaks;
int length = [text textLength];
object_getInstanceVariable(text,"theBreaks",(void **)&theBreaks);
nbreaks = theBreaks->chunk.used;
breaks = theBreaks->breaks;
for(pos=0,line=0;line<nbreaks && pos<length;line++){
int lineChange;
int endParagraph;
int len,nlen;
char *buf;
lineChange = breaks[line] & 0x8000;
endParagraph = breaks[line] & 0x4000;
len = breaks[line] & 0x2fff;
buf = malloc(len+1);
nlen = [text getSubstring:buf start:pos length:len];
buf[nlen] = '\000';
printf("pos=%d len=%d eP=%d buf=%s",
pos,nlen,endParagraph,buf);
free(buf);
pos += len;
if(lineChange!=0){
/* "if the line change bit is set, the descriptor is
* the first field of a NXHeightChange...."
*/
line += sizeof(NXHeightInfo)/sizeof(NXLineDesc);
}
}
return self;
}
@end