How to change the lineSpacing of NSTextView? - macos

I have searched some pages. And I found the answer code like the below...
NSMutableParagraphStyle *para = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
[para setLineSpacing:message.defaultParagraphStyle.lineSpacing + (float)2.5];
[message setDefaultParagraphStyle:(NSParagraphStyle*)para];
But it seems it didn't work. Any idea or any wrong usage here?

That will do it:
CGFloat spacing = 55.0f;
NSMutableParagraphStyle *para =[[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
[para setLineSpacing:spacing];
[para setMinimumLineHeight:spacing];
[para setMaximumLineHeight:spacing];
[yourTextView setDefaultParagraphStyle:para];
NSString *stringWithLineBreak = #"test \n test text \n more test text \n";
[yourTextView setString:stringWithLineBreak];

Related

Incorrect font measures

On a NSTextField I'm setting a custom font with a size of 140. The text is set to #"28". But as you can clearly see on the image, the text field has plenty of space on top. This only happens with certain type of fonts, not all of them. My question is what information from the font could be affecting the textfield that ends up cropping the text ? (Ascender, Cap Height ?). And if so, can I modify the font file to fix it ?
The baseline will vary between fonts. In addition, there are other metrics that vary. You can work around this problem with NSAttributedString. You could try varying the NSBaselineOffsetAttribute and from within a paragraph setMinimumLineHeight and setMaximumLineHeight. The following is an example. Make sure to create two textField labels and connect their outlets.
self.Label1.stringValue = #"Test Text";
//
// baseline is different for each font!
//
//self.Label2.stringValue = #"Test Text";
NSFont *otherFont = [NSFont fontWithName:#"MarkerFelt-Thin" size:40.0f];
NSNumber *baseline = [[NSNumber alloc] initWithFloat: 5.0f];
NSMutableParagraphStyle *paraStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paraStyle setParagraphSpacingBefore:20.0f];
[paraStyle setMinimumLineHeight:30.0f];
[paraStyle setMaximumLineHeight:50.0f];
NSDictionary *otherFDict = [NSDictionary dictionaryWithObjectsAndKeys: paraStyle, NSParagraphStyleAttributeName,
otherFont, NSFontAttributeName, baseline, NSBaselineOffsetAttributeName, nil];
NSMutableAttributedString *otherText = [[NSMutableAttributedString alloc] initWithString:#"Test Text" attributes:otherFDict];
self.Label2.attributedStringValue = otherText;

Trying to get color value of pixel

I'm trying to read the color value of a pixel in a tif image but I can't fihure out the correct way to do it. I'm using OSX and my approach is as follows:
NSImage *picture = [[NSImage alloc] initWithContentsOfFile:#"bais2.tif"]; //file is located in resoureces folder.
NSBitmapImageRep *imageRep = [[picture representations] objectAtIndex:0];
NSColor* color = [imageRep colorAtX:10 y:10];
NSLog(#"%f %f, %f", [color redComponent], [color blueComponent], [color greenComponent]);
The problem is that for some reason the logged values in NSLog always becomes 0.0000000....
I have also tried to use:
NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithData:[picture TIFFRepresentation]];
instead of [[picture representations] objectAtIndex:0] but the result is the same.
I get no error messages or warnings, but I think there is something wrong when i load the picture?
Please help me, what am i doing wrong? And is there a better way to read pixel color data?
Your error is here:
NSImage *picture = [[NSImage alloc] initWithContentsOfFile:#"bais2.tif"];
-------------------------------------------------------------------^^^^
You can use:
NSImage *picture= [NSImage imageNamed:#"bais2.tiff"];
Or :
NSImage *picture = [[NSImage alloc] initWithContentsOfFile:#"bais2.tiff"];
NSData *someNSData = [Image TIFFRepresentation];
NSBitmapImageRep *someNSBitmapImageRepData = [[NSBitmapImageRep alloc] initWithData:someNSData];
NSSize imageSizee = [someNSBitmapImageRepData size];
CGFloat y = imageSize.height - 100.0;
NSColor* color = [someNSBitmapImageRepData colorAtX:100.0 y:y];
NSLog(#"color = %#",color);
output : color = NSCalibratedRGBColorSpace 1 1 1 1

Putting a CVS file into an NSArray to graph with core-plot libararies

I am trying to take a simple excel csv file with x and y values and put it into an NSArray so that I can use it to graph a scatter plot using core-plot. I have already set up code to display a graph with certain data plots here:
JACViewController.m
#import "JACViewController.h"
#implementation JACViewController
#synthesize scatterPlot;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSMutableArray *data = [NSMutableArray array];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(-10, 100)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(-8, 50)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(-6, 20)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(-4, 10)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(-2, 5)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(0, 0)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(2, 4)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(4, 16)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(6, 36)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(8, 64)]];
[data addObject:[NSValue valueWithCGPoint:CGPointMake(10, 100)]];
self.scatterPlot = [[JACSimpleScatterPlot alloc] initWithHostingView:_graphHostingView andData:data];
[self.scatterPlot initialisePlot];
}
#end
But now I want to use a CSV file from excel and display the data that I get from there.
The Excel file looks like this:
a1= "Data X" b1= "Data Y" a2:a8=(1,2,3,4,5,6,7) b2:b8=(10,20,30,40,50,60,70)
Assuming your data is exported as UTF8 text. Pass a URL to the CSV document into this call.
You can use
NSString *exceldata = [NSString stringWithContentsOfURL:aurl encoding:NSUTF8StringEncoding error:&error];
to get the data then split the string into lines with
NSArray *lines = [exceldata componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
finally each line can be split into components with
NSMutableArray *plotdata = [NSMutableArray array];
for(NSString *line in lines)
{
NSArray *points = [line componentsSeparatedByString:#","];
CGFloat xpoint = [[points objectAtIndex:0] floatValue];
CGFloat ypoint = [[points objectAtIndex:1] floatValue];
[plotdata addObject:[NSValue valueWithCGPoint:CGPointMake(xpoint,ypoint)]];
}
This ignores that line 0 is a header and that an empty or malformed line will crash the routine but shows the basic code of what you need to do.

NSAttributedString / NSTextTab Alignment Issue

GOAL:
I'm attempting to use NSAttributedStrings (in conjunction with NSTextTabs) to create the following layout:
[ Title # ] <-- Useable in NSTableViews, NSMenuItems, etc.
[ Another Title # ]
[ T3 # ]
ATTEMPTED SOLUTION:
The code I'm attempting is:
NSMutableParagraphStyle *tabStyle = [[NSMutableParagraphStyle alloc] init];
[tabStyle setTabStops: [NSArray array]];
[tabStyle addTabStop: [[NSTextTab alloc] initWithType: NSRightTabStopType location: 200.0]];
[attrString appendAttributedString: [[NSMutableAttributedString alloc] initWithString: #"\t"]];
[attrString addAttribute: NSParagraphStyleAttributeName value: tabStyle range: NSMakeRange(0, [attrString length])];
[attrString appendAttributedString: [[NSMutableAttributedString alloc] initWithString: #"1"]];
Where attrString is an NSMutableAttributeString, currently set to the "Title".
However, using this code (which I would assume would produce the desired output), produces the following:
FURTHER INFORMATION:
When I remove the references to NSTextTabs, like so:
[attrString appendAttributedString: [[NSMutableAttributedString alloc] initWithString: #"\t"]];
[attrString appendAttributedString: [[NSMutableAttributedString alloc] initWithString: #"1"]];
I get the expected output of uneven tabbing.
BOTTOM LINE:
Why is the NSAttributedString seemingly ignoring the NSParagraphStyle/NSTextTabs?
What can I do to fix this?
Found the issue, by making an NSTextView in IB and placing the AttributedString into it.
Apparently, the layout needs to be "Scrolls" (was "Truncates") in order to produce the desired effect.

NSTextView - using initWithHTML with tables

I'm trying to format some text in NSTextView to be placed in a single line with black background. One piece of text needs to be left aligned, the other piece (but still in the same line) needs to be centered.
NSString *header = [NSString stringWithFormat:
#""
"<table style=\"width: 100%; background: black; "
"color: white; font-family: Arial; "
"font-size: 16px;\"><tr><td>"
"1. zadatak"
"</td><td align=\"center\" width=\"100%\">"
""
"%#"
""
"</td></tr></table>"
"", [self.problemname.stringValue uppercaseString]];
Unfortunately, no matter what width I specify, NSTextView appears to ignore the table width.
Any workarounds, different approaches, or other suggestions?
More info on the background of the problem.
I've written an app for writing tasks for programming contests. Each task author submits content in different format, so getting them to standardize it in a simple bundle would be of great benefit.
I need this for a printing module. I'm taking several NSTextViews and stitching them together.
These contests have the following document formatting which we're supposed to follow - Example PDF (GoogleDocs)
:
Contest header
+------------------------------------------------+
| 1st Task TITLE 20 points |
+------------------------------------------------+
Introductory text here.
Input
Explanation of input data
Output
Explanation of output data
Sample Data
Input: | Input:
abcd | bcde
|
Output: | Output:
efgh | fghi
|
More info: |
info text |
Modification of Apple's sample code for programmatically adding tables to NSAttributedString:
- (NSMutableAttributedString *) printTitleTableAttributedString
{
NSMutableAttributedString *tableString = [[NSMutableAttributedString alloc] initWithString:#"\n\n"];
NSTextTable *table = [[NSTextTable alloc] init];
[table setNumberOfColumns:3];
[tableString appendAttributedString:[self printTitleTableCellAttributedStringWithString:#"1. zadatak\n"
table:table
textAlignment:NSLeftTextAlignment
row:0
column:0]];
[tableString appendAttributedString:[self printTitleTableCellAttributedStringWithString:[self.problemname.stringValue stringByAppendingString:#"\n"]
table:table
textAlignment:NSCenterTextAlignment
row:0
column:1]];
[tableString appendAttributedString:[self printTitleTableCellAttributedStringWithString:#"20 bodova\n"
table:table
textAlignment:NSRightTextAlignment
row:0
column:2]];
[table release];
return [tableString autorelease];
}
- (NSMutableAttributedString *) printTitleTableCellAttributedStringWithString:(NSString *)string
table:(NSTextTable *)table
textAlignment:(NSTextAlignment)textAlignment
row:(int)row
column:(int)column
{
NSColor *backgroundColor = [NSColor colorWithCalibratedRed:0
green:0
blue:0x80/255.
alpha:0xFF];;
NSColor *borderColor = [NSColor whiteColor];
NSTextTableBlock *block = [[NSTextTableBlock alloc]
initWithTable:table
startingRow:row
rowSpan:1
startingColumn:column
columnSpan:1];
[block setBackgroundColor:backgroundColor];
[block setBorderColor:borderColor];
[block setWidth:0.0 type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder];
[block setWidth:2.0 type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding];
NSMutableParagraphStyle *paragraphStyle =
[[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setTextBlocks:[NSArray arrayWithObjects:block, nil]];
[paragraphStyle setAlignment:textAlignment];
[block release];
NSMutableAttributedString *cellString =
[[NSMutableAttributedString alloc] initWithString:string];
[cellString addAttribute:NSParagraphStyleAttributeName
value:paragraphStyle
range:NSMakeRange(0, [cellString length])];
[cellString addAttribute:NSForegroundColorAttributeName
value:[NSColor whiteColor]
range:NSMakeRange(0, [cellString length])];
[paragraphStyle release];
return [cellString autorelease];
}
Then I just append it into the textview:
[printText.textStorage setAttributedString:[self printTitleTableAttributedString]];
NSTextView's HTML support is only rudimentary. It does't hook into WebKit or anything to render full HTML.
The only way I know of that comes even close to accomplishing what you're trying to do with an NSTextView is tab stops. You can add an NSTextTab with an alignment of NSCenterTextAlignment to the line's paragraph style. Then use a tab to separate the left-aligned text from the center-aligned text.
The biggest problem with this is that you have to calculate the center point of your text view and create your tab stop at that location every time the size of your text view changes.
I suppose you could also subclass NSLayoutManager, but that's probably more heavy-handed than you were expecting.

Resources